关于 syncfusion-angular-daterangepicker
syncfusion-angular-daterangepicker 是面向 Angular 开发者的 Syncfusion Essential JS 2 日期范围选择器实现指南。内容涵盖范围选择、预设、校验、事件、无障碍支持和本地化。
主要功能
- 01双日历日期范围选择
- 02预设范围及自定义选项
- 03日期和范围长度限制
- 04事件处理与程序化控制
- 05键盘操作和屏幕阅读器支持
- 06本地化、RTL 与样式定制
适用场景
- 01为报表选择日期范围
- 02设置预订入住和退房日期
- 03筛选分析仪表板的时间范围
- 04在 Angular 表单中创建无障碍日期范围字段
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ angular-ui-components-skills --skill syncfusion-angular-daterangepicker安装后在 Claude Code 中输入/syncfusion-angular-daterangepicker确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-reference.mddate-formatting-and-constraints.mddate-range-selection.mdevents-and-methods.mdgetting-started.mdglobalization-and-localization.mdkeyboard-navigation-and-accessibility.mdpreset-ranges.mdstyling-and-customization.md详细介绍
实现 Syncfusion Angular DateRangePicker
本指南全面介绍如何在 Angular 应用中实现 Syncfusion Essential JS 2 DateRangePicker 组件。了解如何创建日期范围选择器、处理范围选择、管理事件以及自定义样式。
DateRangePicker 概述
Syncfusion Angular DateRangePicker 组件是一款专用的日期选择控件,提供以下功能:
- 双日历显示: 选择开始日期和结束日期,并同步显示日历
- 预设范围: 提供“最近 7 天”“本月”“上月”“自定义”等预定义选项
- 范围验证: 支持最小/最大日期、禁用范围及必需的范围长度
- 日期格式: 可自定义日期格式,并支持分隔符和格式模式
- 事件系统: 提供 created、destroyed、change、select、rangeSelected、open、close、renderDayCell 事件
- 键盘快捷键: 支持 Tab、方向键、Enter、Escape,提供完整的键盘无障碍操作
- 本地化支持: 支持特定区域设置的格式、星期标题和月份名称
- 无障碍功能: 完全符合 WCAG 2.2 标准,支持 ARIA 属性和屏幕阅读器
- 丰富的自定义选项: 支持 CSS 类、自定义模板和日期单元格渲染
- 移动设备优化: 提供便于触控的界面、响应式设计和全屏模式
程序包: @syncfusion/ej2-angular-calendars
文档导航
根据具体需求阅读以下参考文档:
入门
📄 阅读: references/getting-started.md
- 程序包安装和模块设置
- CSS 主题导入和依赖项
- 基本的 DateRangePicker 实现
- 在 Angular 中初始化组件
- 开始日期和结束日期配置
- 运行和测试设置
日期范围选择
📄 阅读: references/date-range-selection.md
- 单击选择日期范围
- 按顺序选择日期(先单击开始日期,再单击结束日期)
- 日期范围值绑定(
startDate、endDate属性) - 最小/最大日期限制
- 范围验证和错误处理
- 禁用日期范围
- 清除所选内容
预设范围
📄 阅读: references/preset-ranges.md
- 预定义范围选项(最近 7 天、上月等)
- 自定义预设配置
- 以编程方式应用预设
- 动态生成预设
- 预设变更事件
- 将预设与限制条件结合使用
事件和方法
📄 阅读: references/events-and-methods.md
- 事件处理程序(change、select、rangeSelected、open、close)
- 范围选择事件详情(startDate、endDate、daySpan)
- 编程方法(show()、hide()、getSelectedRange())
- created 和 destroyed 生命周期事件
- 使用 RenderDayCell 自定义样式
- 方法的返回类型和参数
日期格式和限制条件
📄 阅读: references/date-formatting-and-constraints.md
- 日期格式模式和分隔符
- 支持多种格式(format 和 inputFormats)
- 最小/最大日期限制
- 最小/最大天数验证
- 禁用日期配置
- 格式错误处理
- 特定区域设置的格式
键盘导航和无障碍功能
📄 阅读: references/keyboard-navigation-and-accessibility.md
- Tab 和 Shift+Tab 导航
- 使用方向键导航日期
- 使用 Enter 选择和确认范围
- 使用 Escape 关闭选择器
- Alt 键快捷键
- 屏幕阅读器兼容性
- ARIA 标签和角色
- 符合 WCAG 2.2 AA 标准
- 焦点管理
样式与自定义
📄 阅读: references/styling-and-customization.md
- CSS 类自定义(.e-daterangepicker、.e-calendar、.e-range-header)
- 主题选择(Material、Bootstrap、Tailwind、Fabric)
- 深色模式实现
- 通过 renderDayCell 自定义日期单元格样式
- 禁用日期样式
- 预设按钮样式
- 悬停和焦点状态
- 响应式布局自定义
全球化与本地化
📄 阅读: references/globalization-and-localization.md
- 用于日期格式化的 Locale 属性
- 支持阿拉伯语、希伯来语的 RTL(从右到左)布局
- 星期标题格式(Short、Narrow、Abbreviated、Wide)
- 月份名称和星期名称本地化
- 自定义 Locale 支持
- 时区处理
- 日期格式本地化
API 参考
📄 阅读: references/api-reference.md
- 完整的属性参考及说明
- 所有方法签名及返回类型
- 事件参数类型和结构
- 类型接口(RangeEventArgs、NavigatingEventArgs 等)
- CSS 类和样式钩子
- 浏览器支持矩阵
快速入门示例
// app.component.ts
import { Component } from '@angular/core';
import { RangeEventArgs } from '@syncfusion/ej2-calendars';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// Date range properties
startDate: Date = new Date(2026, 2, 1); // March 1, 2026
endDate: Date = new Date(2026, 2, 31); // March 31, 2026
// Constraints
minDate: Date = new Date(2020, 0, 1);
maxDate: Date = new Date(2030, 11, 31);
// Range display
selectedRange: string = '';
// Event handler
onRangeChange(args: RangeEventArgs): void {
console.log('Start Date:', args.startDate);
console.log('End Date:', args.endDate);
console.log('Days in range:', args.daySpan);
this.updateRangeDisplay();
}
updateRangeDisplay(): void {
if (this.startDate && this.endDate) {
const start = this.startDate.toLocaleDateString();
const end = this.endDate.toLocaleDateString();
this.selectedRange = `${start} - ${end}`;
}
}
}
<div style="padding: 20px; font-family: Arial, sans-serif;">
<h2>DateRangePicker Example</h2>
<div style="margin-bottom: 20px;">
<label for="dateRange">Select Date Range:</label>
<ejs-daterangepicker
id="dateRange"
placeholder="Select a date range"
[startDate]="startDate"
[endDate]="endDate"
[min]="minDate"
[max]="maxDate"
(change)="onRangeChange($event)">
</ejs-daterangepicker>
</div>
<div *ngIf="selectedRange" style="padding: 10px; background-color: #f0f0f0;">
<p><strong>Selected Range:</strong> {{ selectedRange }}</p>
</div>
</div>
/* app.component.css */
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material3.css';
:host ::ng-deep .e-daterangepicker {
margin: 10px 0;
width: 100%;
}
:host ::ng-deep .e-range-header {
background-color: #3f51b5;
color: white;
}
常见模式
模式 1:预设日期范围
用于常见日期范围的快速选择按钮:
export class AppComponent {
presets: any[] = [
{ label: 'Today', start: new Date(), end: new Date() },
{ label: 'Last 7 Days', start: this.getDateDaysAgo(7), end: new Date() },
{ label: 'Last 30 Days', start: this.getDateDaysAgo(30), end: new Date() },
{ label: 'This Month', start: this.getFirstDayOfMonth(), end: new Date() },
{ label: 'Last Month', start: this.getFirstDayOfLastMonth(), end: this.getLastDayOfLastMonth() }
];
startDate: Date = new Date();
endDate: Date = new Date();
selectPreset(preset: any): void {
this.startDate = preset.start;
this.endDate = preset.end;
}
private getDateDaysAgo(days: number): Date {
const date = new Date();
date.setDate(date.getDate() - days);
return date;
}
private getFirstDayOfMonth(): Date {
return new Date(new Date().getFullYear(), new Date().getMonth(), 1);
}
private getFirstDayOfLastMonth(): Date {
const date = new Date();
return new Date(date.getFullYear(), date.getMonth() - 1, 1);
}
private getLastDayOfLastMonth(): Date {
const date = new Date();
return new Date(date.getFullYear(), date.getMonth(), 0);
}
}
<div>
<div style="margin-bottom: 10px;">
<button *ngFor="let preset of presets"
(click)="selectPreset(preset)"
style="margin-right: 5px; padding: 8px 12px;">
{{ preset.label }}
</button>
</div>
<ejs-daterangepicker
[startDate]="startDate"
[endDate]="endDate">
</ejs-daterangepicker>
</div>
模式 2:日期范围验证
使用自定义约束验证日期范围:
export class AppComponent {
@ViewChild('daterangepicker') drp!: DateRangePickerComponent;
startDate: Date = new Date();
endDate: Date = new Date();
rangeError: string = '';
minDate: Date = new Date(2020, 0, 1);
maxDate: Date = new Date(2030, 11, 31);
minDays: number = 1; // At least 1 day
maxDays: number = 90; // At most 90 days
onRangeChange(args: RangeEventArgs): void {
this.rangeError = '';
// Validate date range
if (args.daySpan < this.minDays) {
this.rangeError = `Range must be at least ${this.minDays} day(s)`;
return;
}
if (args.daySpan > this.maxDays) {
this.rangeError = `Range cannot exceed ${this.maxDays} days`;
return;
}
this.startDate = args.startDate;
this.endDate = args.endDate;
}
isRangeValid(): boolean {
return this.rangeError === '';
}
}
模式 3:响应式表单集成
将 DateRangePicker 集成到响应式表单中:
export class AppComponent implements OnInit {
reportForm: FormGroup;
constructor(private fb: FormBuilder) {
this.reportForm = this.fb.group({
reportName: ['', Validators.required],
startDate: [new Date(2026, 0, 1), Validators.required],
endDate: [new Date(), Validators.required]
});
}
ngOnInit(): void {
this.reportForm.get('startDate')?.valueChanges.subscribe(date => {
console.log('Start date changed:', date);
this.validateDateRange();
});
this.reportForm.get('endDate')?.valueChanges.subscribe(date => {
console.log('End date changed:', date);
this.validateDateRange();
});
}
validateDateRange(): void {
const start = this.reportForm.get('startDate')?.value;
const end = this.reportForm.get('endDate')?.value;
if (start && end && start > end) {
this.reportForm.get('endDate')?.setErrors({ 'invalidRange': true });
} else {
this.reportForm.get('endDate')?.setErrors(null);
}
}
submitForm(): void {
if (this.reportForm.valid) {
console.log('Form values:', this.reportForm.value);
}
}
}
<form [formGroup]="reportForm" (ngSubmit)="submitForm()">
<div>
<label>Report Name:</label>
<ejs-textbox
formControlName="reportName"
placeholder="Enter report name">
</ejs-textbox>
</div>
<div>
<label>Report Period:</label>
<ejs-daterangepicker
[formControl]="reportForm.get('startDate')"
[endDate]="reportForm.get('endDate')?.value">
</ejs-daterangepicker>
</div>
<button type="submit" [disabled]="!reportForm.valid">Generate Report</button>
</form>
模式 4:动态范围约束
根据业务逻辑更新范围约束:
export class AppComponent {
startDate: Date = new Date();
endDate: Date = new Date();
// Dynamic constraints
minDate: Date = new Date();
maxDate: Date = new Date();
reportType: string = 'daily';
onReportTypeChange(type: string): void {
this.reportType = type;
this.updateConstraints();
}
private updateConstraints(): void {
const today = new Date();
switch (this.reportType) {
case 'daily':
// Last 7 days only
this.minDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
this.maxDate = today;
break;
case 'monthly':
// Last 12 months
this.minDate = new Date(today.getFullYear() - 1, today.getMonth(), 1);
this.maxDate = today;
break;
case 'yearly':
// Last 5 years
this.minDate = new Date(today.getFullYear() - 5, 0, 1);
this.maxDate = today;
break;
}
}
}
模式 5:禁用日期范围
禁用特定日期范围(节假日、不可选日期):
export class AppComponent {
disabledRanges: Array<{start: Date, end: Date}> = [
{ start: new Date(2026, 11, 20), end: new Date(2026, 11, 31) }, // Christmas season
{ start: new Date(2026, 0, 1), end: new Date(2026, 0, 3) } // New Year
];
startDate: Date = new Date();
endDate: Date = new Date();
onRenderDayCell(args: RenderDayCellEventArgs): void {
// Disable dates in disabled ranges
for (const range of this.disabledRanges) {
if (args.date >= range.start && args.date <= range.end) {
args.isDisabled = true;
break;
}
}
}
}
关键属性参考
| 属性 | 类型 | 说明 | 示例 |
|---|---|---|---|
startDate | Date | 范围的开始日期 | [startDate]="start" |
endDate | Date | 范围的结束日期 | [endDate]="end" |
value | Date[] or DateRange | 选定的日期范围(数组或对象) | [(ngModel)]="dateRange" |
min | Date | 可选日期的最早日期 | [min]="minDate" |
max | Date | 可选日期的最晚日期 | [max]="maxDate" |
minDays | number | 范围内的最少天数 | [minDays]="1" |
maxDays | number | 范围内的最多天数 | [maxDays]="90" |
format | string | 日期显示格式 | format="dd/MM/yyyy" |
separator | string | 范围分隔符 | separator=" to " |
placeholder | string | 占位文本 | placeholder="Select date range" |
presets | PresetsModel[] | 预定义的范围选项 | [presets]="presets" |
strictMode | boolean | 严格日期验证 | [strictMode]="true" |
readonly | boolean | 只读输入框 | [readonly]="false" |
enabled | boolean | 启用/禁用组件 | [enabled]="true" |
locale | string | 语言区域/语言代码 | locale="en-US" |
enableRtl | boolean | 启用 RTL 布局 | [enableRtl]="false" |
cssClass | string | 自定义 CSS 类 | cssClass="custom-drp" |
width | number | string | 组件宽度 | width="300px" |
allowEdit | boolean | 允许手动输入文本 | [allowEdit]="true" |
openOnFocus | boolean | 输入框获得焦点时打开选择器 | [openOnFocus]="true" |
showClearButton | boolean | 显示清除按钮 | [showClearButton]="true" |
depth | CalendarView | 日历视图深度 | depth="Month" |
常见使用场景
使用场景 1:报告日期范围选择
- 用户选择生成报告的日期范围
- 应用最小/最大日期限制
- 支持预设范围(最近 7 天、上个月等)
- 解决方案:结合 startDate/endDate、预设范围以及最小/最大日期限制
- 参考:预设范围 + 日期格式与限制
使用场景 2:预订系统日期范围
- 选择预订的入住和退房日期
- 禁用过去的日期和不可预订日期
- 显示范围内的天数
- 解决方案:使用最小日期限制,通过 renderDayCell 禁用日期范围,并计算 daySpan
- 参考:日期范围选择 + 事件与方法
使用场景 3:分析日期筛选器
使用场景 4:无障碍表单字段
- 在表单中集成 DateRangePicker,并确保完整的键盘无障碍支持
- 兼容屏幕阅读器,符合 WCAG 2.2 标准
- 解决方案:与 Reactive Forms 配合使用,并设置适当的 ARIA 标签
- 参考:键盘导航与无障碍
使用场景 5:国际化日期选择器
- 支持多种语言和日期格式
- 为阿拉伯语、希伯来语显示 RTL 布局
- 采用特定于区域设置的格式
- 解决方案:使用 locale 属性并自定义格式
- 参考:全球化与本地化
相关技能
- 实现 Syncfusion Angular 组件 - 所有 Angular 组件的主要库指南
- 日历 - 用于选择日期的单日历组件
- 日期选择器 - 带日历覆盖层的单日期选择器
- 日期时间选择器 - 日期和时间组合选择
- 时间选择器 - 时间选择组件
后续步骤: 根据具体需求选择上述参考指南,或查看常见模式部分,了解适用于你使用场景的模式。