繁体   English   中英

带范围选择的角度材料日期选择器

[英]Angular Material Datepicker with Range Selection

我正在使用 angular 8 并且我想实现一个日期选择器并突出显示日期:在此处输入图像描述我正在寻找一些这样的包: https ://www.npmjs.com/package/saturn-datepicker 不幸的是它已被弃用目前我找不到其他类似的人。 你知道什么是为了我的目的吗? 谢谢你。

在物料日期选择器中,您可以定义最大值和最小值。

例如:

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();

重要更新,我的好!! 谷歌有很多像我这样的控件! (记住:谷歌是我的朋友,谷歌是我的朋友......)

我正在这个stackblitz 中创建一个 datePicker 范围,我会在之后尝试解释

更新我改进了stackblitz和一个简短的解释

mat-date-picker 有一点很重要,即无法创建日模板。 所以有必要使用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 将管理 td 以添加/删除鼠标悬停的侦听器。 必须包含在 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-menu 打开 mat-calendar 所需的其余功能来自另一个 SO 在这最后一个 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-form-field 中使用组件,比如

<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-input 一样移动。 为此,我们需要添加一些功能,请参阅(我保证这是最后一个) 最近的 SO

注意:控件是“按原样”,没有任何保证,并且允许:批评它、改进、修改、使用或将其作为坏例子

在角材料中有一个选项来指定范围https://material.angular.io/components/datepicker/overview#date-range-selection

<mat-form-field appearance="fill">
  <mat-label>Enter a date range</mat-label>
  <mat-date-range-input [rangePicker]="picker">
    <input matStartDate placeholder="Start date">
    <input matEndDate placeholder="End date">
  </mat-date-range-input>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>

https://stackblitz.com/angular/pydjpbqmvqq?file=src%2Fapp%2Fdate-range-picker-overview-example.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM