Angular 16 Material日期范围选择器:禁用起始日期后指定天数后的日期
解决Angular Material 16日期范围选择器实时限制结束日期的问题
因为启用操作按钮后,表单控件的值仅在点击Apply后才会更新,常规的dateChange/dateInput事件无法实时捕获面板内选中的起始日期。要实现实时限制结束日期的可选范围,需要利用MatDateRangePicker提供的selectedChanged事件——这个事件会在面板内选中日期(无论是否点击Apply)时立即触发,能实时获取当前选中的日期范围。
具体实现步骤:
- 组件类中定义临时变量与过滤函数
在组件的TypeScript代码中,添加临时变量存储面板内选中的起始日期,同时编写自定义日期过滤函数:
import { Component } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { DateRange } from '@angular/material/datepicker'; @Component({ selector: 'app-date-range-picker', templateUrl: './date-range-picker.component.html', styleUrls: ['./date-range-picker.component.css'] }) export class DateRangePickerComponent { dateFilterForm: FormGroup; currentDate = new Date(); // 存储面板内临时选中的起始日期 tempStartDate: Date | null = null; // 允许的日期跨度(示例为4天) allowedDaysSpan = 4; constructor(private fb: FormBuilder) { this.dateFilterForm = this.fb.group({ start: [null], end: [null] }); } // 监听面板内选中的日期范围变化 onSelectedRangeChange(range: DateRange<Date | null>) { this.tempStartDate = range.start; } // 自定义日期过滤函数,限制结束日期可选范围 endDateFilter = (date: Date | null): boolean => { if (!date || !this.tempStartDate) { // 没有临时起始日期时,只限制不超过当前日期 return date <= this.currentDate; } // 计算起始日期+4天后的日期 const maxAllowedDate = new Date(this.tempStartDate); maxAllowedDate.setDate(maxAllowedDate.getDate() + this.allowedDaysSpan); // 结束日期必须在起始日期和maxAllowedDate之间,且不超过当前日期 return date >= this.tempStartDate && date <= maxAllowedDate && date <= this.currentDate; }; onSelectDate() { // 点击Apply后的逻辑,比如提交表单等 console.log('Selected range:', this.dateFilterForm.value); } // 点击Cancel时清空临时起始日期,恢复过滤逻辑 onCancel() { this.tempStartDate = null; } }
- 修改模板代码
给mat-date-range-picker绑定selectedChanged事件,同时给结束日期输入框添加[dateFilter]绑定:
<mat-form-field class="custom-datepicker"> <mat-date-range-input [formGroup]="dateFilterForm" [rangePicker]="rangePicker" [max]="currentDate" > <input #matStartDate matStartDate placeholder="Start date" formControlName="start" /> <input #matEndDate matEndDate placeholder="End date" formControlName="end" [dateFilter]="endDateFilter" /> </mat-date-range-input> <mat-datepicker-toggle matSuffix [for]="rangePicker"></mat-datepicker-toggle> <mat-date-range-picker #rangePicker (selectedChanged)="onSelectedRangeChange($event)"> <mat-date-range-picker-actions> <button mat-button matDateRangePickerCancel (click)="onCancel()" i18n="@@cancel">Cancel</button> <button mat-raised-button color="primary" matDateRangePickerApply (click)="onSelectDate()" > Apply </button> </mat-date-range-picker-actions> </mat-date-range-picker> </mat-form-field>
关键说明:
selectedChanged事件会在面板内每次选中日期(包括起始和结束日期变更)时触发,实时更新临时起始日期tempStartDate。endDateFilter函数会根据tempStartDate动态计算结束日期的可选范围:只能选择起始日期到起始日期+4天之间的日期,且不超过当前日期。- 点击Cancel按钮时清空
tempStartDate,让日期过滤逻辑恢复到初始状态。
内容的提问来源于stack exchange,提问作者Carlos Daniel Gomes
相关产品推荐
相关产品推荐

