Angular Материал Datepicker с выбором диапазона - PullRequest
1 голос
/ 16 февраля 2020

Я использую angular 8, и я хотел внедрить средство выбора даты с выделенным daterage: введите описание изображения здесь Я искал какой-то пакет, подобный этому: https://www.npmjs.com/package/saturn-datepicker К сожалению, это устарело, и в настоящее время я не могу найти других таких. Ты знаешь что-то для моей цели? Спасибо.

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

ВАЖНОЕ ОБНОВЛЕНИЕ , хорошо! Google полон элементов управления, как у меня! (помните: Google - мой друг, Google - мой друг ...)

Я делаю диапазон DatePicker в этом stackblitz , я попытаюсь объяснить после

Обновление Я улучшаю стекаблитц и краткое объяснение

Для средства выбора дат даты важен тот факт, что невозможно создать шаблон дня. Поэтому необходимо использовать Renderer2 для добавления слушателя, добавления классов или удаления классов. Мне нужно использовать document.querySelectorAll, поскольку он показывает в этот другой SO

Идея состоит в том, чтобы с выделенными ячейками создать массив объектов

{
   date: //will be a getTime of the date,
   element: //will be the nativeElement x,
   change: //a boolean to indicate this cell has an aditional class
   x.listen: //the listener added to allow us remove the listener
}

И функцию кто поможет нам добавить / удалить класс в соответствии с двумя переменными: this._dateTo и другой переменной, которая будет this._dateFrom или другой (ранее мы узнали, почему)

  redrawCells(timeTo: number) {
    timeTo = timeTo || this._dateTo;
    if (timeTo<this._dateFrom)
      timeTo=this._dateFrom
    this.cells.forEach(x => {
      const change = x.date >= this._dateFrom && x.date <= timeTo;
      if (change || x.change) {
        x.change = change;
        const addInside = x.change ? "addClass" : "removeClass";
        const addFrom = x.date == this._dateFrom? "addClass":
                        x.date == timeTo && this._dateFrom==timeTo? "addClass":
                        "removeClass";
        const addTo = x.date == timeTo? "addClass": 
                      x.date == this._dateFrom && this._dateFrom==timeTo? "addClass":
                        "removeClass";

        this.renderer[addInside](x.element, "inside");
        this.renderer[addFrom](x.element, "from");
        this.renderer[addTo](x.element, "to");
      }
    });
  }

Новая функция setCell будет управлять тд, чтобы добавить / удалить слушатель мыши над. Это необходимо, заключенное в setTimeout, потому что мы вызываем эту функцию до того, как будет нарисован календарь

  setCells() {
    setTimeout(() => {
      if (this.cells) {
        this.cells.forEach(x => {
          x.listen();  //<---remove the listener
        });
      }
      this.dateOver = null;
      //get the elements
      let elements = document.querySelectorAll(".calendar");
      if (!elements || elements.length == 0) return;
      const cells = elements[0].querySelectorAll(".mat-calendar-body-cell");
      this.cells = [];
      //with each element we fill our array "this.cells"
      cells.forEach((x, index) => {
        const date = new Date(x.getAttribute("aria-label"));
        const time=new Date(date.getFullYear() +"-" +(date.getMonth() + 1) +
              "-" +date.getDate()).getTime()

        this.cells.push({
          date: time,
          element: x,
          change:time>=this._dateFrom && time<=this._dateTo
        });
      });
      this.cells.forEach(x => {
        if (!x.listen) {
          //we add a listener "mouseover"
          x.listen = this.renderer.listen(x.element, "mouseover", () => {
            if (!this._dateTo && this.dateOver != x.date) {
              this.dateOver = x.date;
              this.redrawCells(this.dateOver); //who call to redrawCells
            }
          });
        }
      });
    });
  }

Ну, а остальные функции, необходимые для анализа и форматирования даты и открытия календаря с использованием меню mat, с это еще один ТАК . В этом последнем SO календарь не закрывается, поэтому мы можем использовать два щелчка, чтобы получить dateFrom и dateTo

  select(date: any) {
    date = new Date(
      date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate()
    );
    if (
      !this.from.value ||
      (this.from.value && this.to.value) ||
      this._dateFrom > date.getTime()
    ) {
      this.dateFrom = date;
      this.dateTo = null;
      this.redrawCells(date.getTime());
    } else {
      this.dateTo = date;
      this.trigger.closeMenu();
    }
  }

Мне нравится создавать пользовательский компонент mat. Это позволяет нам использовать компонент в поле mat-form, например,

<mat-form-field class="full-width" >
  <mat-label>Select dates</mat-label>
  <date-picker-range [formControl]="control" placeholder="DD/MM/YYYY"  ></date-picker-range>
  <mat-error>required</mat-error>
</mat-form-field>

, и, например, разрешить нам использовать [disabled], чтобы отключить formControl, и метка переместится как другой вход mat. Для этого нам нужно добавить некоторые функции, см. (Обещаю, что это последняя) эта последняя последняя версия SO

ПРИМЕЧАНИЕ. Элемент управления «КАК ЕСТЬ» без каких-либо гарантий, и он разрешен: критикуйте его , улучшить, изменить, использовать или поставить как плохой пример

1 голос
/ 16 февраля 2020

В инструменте выбора даты материала вы можете определить максимальные и минимальные значения.

Например:

example.hml <input matInput [min]="minValue" [max]="maxValue" [matDatepicker]="picker" formControlName="name"/> <mat-datepicker #voltageToDatePiker [startAt]="tomorrow"></mat-datepicker>

example.ts minValue = new Date(); maxValue = new Date();

...