0

我有很多天,可以是任何一年。我正在尝试自定义 Angular Material datepicker 以突出显示月份选择视图中的某些月份,以及基于天数的年份选择视图中的某些年份。

.html

<input [matDatepicker]="picker" />
<i class="fas fa-chevron-down"></i>
<mat-datepicker #picker></mat-datepicker>

.ts

arrayOfDays = [new Date('2019-01-01'), new Date('2020-08-10'),  new Date('2020-09-20')];

我想要实现的是在年视图中突出显示 2019 年和 2020 年如果选择了 2019 年,则突出显示 JAN 月,如果选择了 2020 年,则在红色边框中突出显示 MAY 和 AUG ,当前月份和年份除外,如下所示图片。

月份突出显示 年份突出显示

这可能吗?

我搜索了很多并尝试使用 dateClass,(yearSelected)事件等,但它不适用于 Months 和 Years .. 如果有人知道,如何做到这一点,请帮助..

仅供参考 - https://stackblitz.com/edit/angular-date-class-filter-aactjv 这是我发现将自定义设计设置为日期视图的那个..但我希望对年和月视图进行类似的实现..谢谢进步..

4

1 回答 1

1

实际上,控制材料角度日期选择器事件有点复杂。我不知道是否有更好的方法,但是您可以使用自定义标头组件来获取它,请参阅此SO

之前,我们要创建一个 dataService

@Injectable({
  providedIn: "root"
})
export class DataService {
  arrayOfDays = [
    new Date("2019-01-01"),
    new Date("2020-08-10"),
    new Date("2020-09-20")
  ];

  constructor() {}
  displayMonth(year: number, view: string) {
    setTimeout(() => {
      let elements = document.querySelectorAll(".mat-calendar-content");
      let x = elements[0].querySelectorAll(".mat-calendar-body-cell-content");
      if (view == "multi-year") {
        const years = this.arrayOfDays.map(x => x.getFullYear());
        x.forEach((y: any) => {
          if (years.indexOf(+y.innerHTML) >= 0) {
            {
              y.style["border-color"] = "red";
            }
          }
        });
      }
      if (view=="year"){
        const monthsIni = [
          "JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"
        ];
        const months = this.arrayOfDays
          .filter(x => x.getFullYear() == year)
          .map(x => monthsIni[x.getMonth()]);
        x.forEach((y: any) => {
          if (months.indexOf(y.innerHTML) >= 0) {
            {
              y.style["border-color"] = "red";
            }
          }
        });
      }
    });
  }
}

在 ExampleHeader 和组件中注入 dataService 后,在 Example 标头中是一个复杂的但它只是写

  constructor(_intl: MatDatepickerIntl,
              @Inject(forwardRef(() => MatCalendar)) calendar: MatCalendar<any>,
              @Optional() _dateAdapter: DateAdapter<any>,
              @Optional() @Inject(MAT_DATE_FORMATS) _dateFormats: MatDateFormats,
              changeDetectorRef: ChangeDetectorRef
              ,private dataService:DataService
              ) {
    super(_intl,calendar,_dateAdapter,_dateFormats,changeDetectorRef)
  }

当处理用户点击期间标签时,用户点击上一个按钮,用户点击下一个按钮调用服务

  currentPeriodClicked(): void {
    this.calendar.currentView =
      this.calendar.currentView == "month" ? "multi-year" : "month";
    this.dataService.displayMonth(
      this.calendar.activeDate.getFullYear(),
      this.calendar.currentView
    );
  }

  customPrev(): void {
    this.previousClicked();
    this.dataService.displayMonth(
      this.calendar.activeDate.getFullYear(),
      this.calendar.currentView
    );
  }

  customNext(): void {
    this.nextClicked();
    this.dataService.displayMonth(
      this.calendar.activeDate.getFullYear(),
      this.calendar.currentView
    );
  }

此外,我们还需要在年中从主要组件中选择

  yearSelected(event: any) {
    this.dataService.displayMonth(
      event.getFullYear(),
      this.calendar.currentView
    );
  }

你可以在stackblitz中看到

如果只想“备注”月份的更新(yearSelected),事情就更简单了,因为我们只需要控制事件,所以我们可以忘记自定义标题。

<mat-datepicker #picker [dateClass]="dateClass"
 (yearSelected)="yearSelected($event)"  
 [calendarHeaderComponent]="exampleHeader">
</mat-datepicker>

months = [0,3] //<--in a variable the months we want remark

yearSelected(event:any)
  {
    setTimeout(()=>{
        let elements = document.querySelectorAll(".mat-calendar-content");
        let x = elements[0].querySelectorAll(".mat-calendar-body-cell-content");
        x.forEach((y: any,month:number) => {
          if (this.months.indexOf(month) >= 0) {
            {
              y.style["border-color"] = "red";
            }
          }
        });
      }
    )
  }

stackblitz

于 2020-07-19T22:35:03.227 回答