Material datePicker (Angular) 中的多个日期选择

Vin*_*h A 8 datepicker angular-material angular angular-material-datetimepicker mat-datepicker

我要求用户可以在日期选择器中选择多个日期。如何在 Angular Material 日期选择器中实现多个日期选择功能?

日期选择器

我通过dateClass尝试了这个。但是,每次选择日期后,日期选择器都会关闭。

这是我尝试过的

HTML代码:

<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker [dateClass]="dateClass" #picker></mat-datepicker>
Run Code Online (Sandbox Code Playgroud)

打字稿代码:

dateClass = (d: Date) => {
    const date = d.getDate();

    // Highlight the 1st and 20th day of each month.
    return (date === 1 || date === 5 || date === 14 || date === 19 || date === 21 ) ? 'example-custom-date-class' : undefined;
}
Run Code Online (Sandbox Code Playgroud)

Eli*_*seo 16

您需要直接使用 mat-calendar,您可以将其包含在 mat 菜单和 div 中以避免“关闭”,请参阅

<button mat-icon-button [matMenuTriggerFor]="appMenu">
  <mat-icon>calendar_today</mat-icon>
</button>
<mat-menu #appMenu="matMenu">
    <div (click)="$event.stopPropagation()">
        <mat-calendar #calendar 
           (selectedChange)="select($event,calendar)" 
            [dateClass]="isSelected">
        </mat-calendar>
    </div>
</mat-menu>
Run Code Online (Sandbox Code Playgroud)

我选择以 yyyy-MM-dd (*) 的方式将日期的值存储在字符串中,所以

进口:

import { Component,ViewEncapsulation} from "@angular/core";
Run Code Online (Sandbox Code Playgroud)

代码:

daysSelected: any[] = [];
event: any;

isSelected = (event: any) => {
  const date =
    event.getFullYear() +
    "-" +
    ("00" + (event.getMonth() + 1)).slice(-2) +
    "-" +
    ("00" + event.getDate()).slice(-2);
  return this.daysSelected.find(x => x == date) ? "selected" : null;
};

select(event: any, calendar: any) {
  const date =
    event.getFullYear() +
    "-" +
    ("00" + (event.getMonth() + 1)).slice(-2) +
    "-" +
    ("00" + event.getDate()).slice(-2);
  const index = this.daysSelected.findIndex(x => x == date);
  if (index < 0) this.daysSelected.push(date);
  else this.daysSelected.splice(index, 1);

  calendar.updateTodaysDate();
}
Run Code Online (Sandbox Code Playgroud)

最后 .css 很简单:

.mat-calendar-body-cell.selected
{
  background-color:red!important;
  border-radius: 50%
}
.drop-calendar
{
  width:30rem
}
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记在组件中将封装设置为 none:

encapsulation:ViewEncapsulation.None
Run Code Online (Sandbox Code Playgroud)

更新为什么在styles.css中使用ViewEncapsulation.None和其他方法

问题是如何为所选日期添加颜色。当我们在 mat-calendar 中使用时[dateclass],我们创建了一个函数,该函数接收日期(每月的每一天)作为参数,并返回一个带有您想要的类名称的字符串。在代码中,如果日期在选定的数组中,则该类被“选定”。

但是如果我们不使用 ViewEncapsulation.None 或者我们放入了styles.css(或styles.scss)(**),则不会考虑到这一点。是的,这种样式必须以“全局”样式定义。(记住 ViewEncapsulation.None 使组件中定义的样式变为“全局”

注意:如果您使用 ViewEncapsulation.None 在 stackblitz 中“玩”,请记住您需要刷新 stackblitz,因为样式仍然保存。

(**) 记住在 angular.json 中包含在“样式”中

"styles": [
 "src/styles.scss"
],
Run Code Online (Sandbox Code Playgroud)

你可以在stackblitz中看到

(*) 您可以选择,例如存储所选日期的 getTime()。这个想法是你需要在数组“daysSelected”中找到它,否则,如果你直接使用对象日期,你需要将日期中的年、月和日与数组的元素进行比较。这会导致性能不佳。认为函数“isSelected”在一个月内被调用多少次,每次点击完成


Rus*_*man 6

另一种方法(有点黑客):StackBlitz

只是临时将close方法重写为空函数,更改后返回。还调用平日重新渲染函数。这不是安全和理想的解决方案,但有效。

可能对某人有用。

UPD:或者,您可以使用ngx-multiple-dates包。有一些例子