Material datePicker (Angular) 中的多个日期 Select
Multiple Date Select in Material datePicker (Angular)
我要求用户可以在日期选择器中 select 多个日期。如何在 Angular Material 日期选择器中实现多日期 select 功能?
我通过 dateClass 尝试了这个。但是,在每个日期 selection 之后,日期选择器将关闭。
这是我试过的
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>
打字稿代码:
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;
}
你需要直接用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>
我选择以 yyyy-MM-dd (*) 的方式将日期值存储在字符串中,所以
进口:
import { Component,ViewEncapsulation} from "@angular/core";
TS代码:
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();
}
最后 .css 很简单:
.mat-calendar-body-cell.selected
{
background-color:red!important;
border-radius: 50%
}
.drop-calendar
{
width:30rem
}
注意:不要忘记在组件中将封装设置为 none:
encapsulation:ViewEncapsulation.None
更新 为什么在styles.css
中使用ViewEncapsulation.None和其他方法
问题是如何给所选日期上色。当我们在 mat-calendar [dateclass]
中使用时,我们创建了一个函数,它接收作为参数的日期(每个月的每一天)和 return 一个带有 class 你的名字的字符串想。在代码中,如果日期在所选数组中,则 class 为 'selected'。
但是如果我们不使用 ViewEncapsulation.None 或我们输入 styles.css(或 styles.scss)(**),则不会考虑在内。是的,这种样式必须以“全局”样式定义。 (请记住,ViewEncapsulation.None 使组件中定义的样式变为“全局”
注意:如果您使用 ViewEncapsulation.None 在 stackblitz 中“玩”,请记住您需要刷新 stackblitz,因为样式仍然保存。
(**) 请记住 angular.json 包含在“样式”中
"styles": [
"src/styles.scss"
],
你可以在stackblitz
中看到
(*) 你可以选择,例如存储所选日期的 getTime()。这个想法是你需要在数组“daysSelected”中找到它,否则,如果你直接使用一个对象日期,你需要将日期中的年、月和日与数组的元素进行比较。这会导致性能不佳。认为函数“isSelected”被调用了多少次天有一个月,每次点击完成
另一种方式(有点黑客):StackBlitz
只是暂时将 close 方法重写为空函数,return 更改后返回。
还调用工作日重新渲染功能。
不是安全和理想的解决方案,但有效。
可能对某人有用。
UPD: 或者,您可以使用 ngx-multiple-dates package. There are some examples of it.
我要求用户可以在日期选择器中 select 多个日期。如何在 Angular Material 日期选择器中实现多日期 select 功能?
我通过 dateClass 尝试了这个。但是,在每个日期 selection 之后,日期选择器将关闭。
这是我试过的
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>
打字稿代码:
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;
}
你需要直接用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>
我选择以 yyyy-MM-dd (*) 的方式将日期值存储在字符串中,所以
进口:
import { Component,ViewEncapsulation} from "@angular/core";
TS代码:
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();
}
最后 .css 很简单:
.mat-calendar-body-cell.selected
{
background-color:red!important;
border-radius: 50%
}
.drop-calendar
{
width:30rem
}
注意:不要忘记在组件中将封装设置为 none:
encapsulation:ViewEncapsulation.None
更新 为什么在styles.css
中使用ViewEncapsulation.None和其他方法问题是如何给所选日期上色。当我们在 mat-calendar [dateclass]
中使用时,我们创建了一个函数,它接收作为参数的日期(每个月的每一天)和 return 一个带有 class 你的名字的字符串想。在代码中,如果日期在所选数组中,则 class 为 'selected'。
但是如果我们不使用 ViewEncapsulation.None 或我们输入 styles.css(或 styles.scss)(**),则不会考虑在内。是的,这种样式必须以“全局”样式定义。 (请记住,ViewEncapsulation.None 使组件中定义的样式变为“全局”
注意:如果您使用 ViewEncapsulation.None 在 stackblitz 中“玩”,请记住您需要刷新 stackblitz,因为样式仍然保存。
(**) 请记住 angular.json 包含在“样式”中
"styles": [
"src/styles.scss"
],
你可以在stackblitz
中看到(*) 你可以选择,例如存储所选日期的 getTime()。这个想法是你需要在数组“daysSelected”中找到它,否则,如果你直接使用一个对象日期,你需要将日期中的年、月和日与数组的元素进行比较。这会导致性能不佳。认为函数“isSelected”被调用了多少次天有一个月,每次点击完成
另一种方式(有点黑客):StackBlitz
只是暂时将 close 方法重写为空函数,return 更改后返回。 还调用工作日重新渲染功能。 不是安全和理想的解决方案,但有效。
可能对某人有用。
UPD: 或者,您可以使用 ngx-multiple-dates package. There are some examples of it.