Create consistent cross-browser and cross-device Angular date range picker.
Available in Other JavaScript Frameworks
CoreUI Angular Date Range Picker Component is also available for Bootstrap, React, and Vue. Explore framework-specific implementations below:
Examples
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-example',
templateUrl: './date-range-picker-example.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerExampleComponent {
date = new Date();
startDate = new Date(this.date.getFullYear(), this.date.getMonth(), 11);
endDate = new Date(this.date.getFullYear(), this.date.getMonth(), 17);
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker selectAdjacentDays />
</c-col>
<c-col lg="6">
<c-date-range-picker [startDate]="startDate" [endDate]="endDate" />
</c-col>
</c-row>
With footer
import { DatePipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import {
ButtonDirective,
ColComponent,
DateRangePickerComponent,
DropdownCloseDirective,
RowComponent,
TemplateIdDirective
} from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-with-footer',
templateUrl: './date-range-picker-with-footer.component.html',
imports: [
RowComponent,
ColComponent,
DateRangePickerComponent,
TemplateIdDirective,
ButtonDirective,
DropdownCloseDirective,
DatePipe
]
})
export class DateRangePickerWithFooterComponent {
public date = new Date();
readonly startDate = signal<Date | null>(new Date(new Date().setDate(this.date.getDate() + 1)));
readonly endDate = signal<Date | null>(new Date(new Date().setDate(this.date.getDate() + 3)));
readonly calendarDate = signal(new Date(Date.now()));
onToday() {
this.calendarDate.set(new Date(Date.now()));
}
onClear() {
this.startDate.set(null);
this.endDate.set(null);
}
}<c-row>
<c-col lg="6">
<c-date-range-picker
#dateRangePicker="cDateRangePicker"
[(endDate)]="endDate"
[(startDate)]="startDate"
[calendarDate]="calendarDate()"
>
<ng-template cTemplateId="datePickerFooter" let-dropdown>
<button (click)="onToday()" cButton class="me-auto" color="danger" size="sm" variant="ghost">Today</button>
<button (click)="onClear()" cButton color="primary" size="sm">Clear</button>
<button [disabled]="!endDate" [dropdownComponent]="dropdown" cButton cDropdownClose color="primary"size="sm">OK</button>
</ng-template>
</c-date-range-picker>
</c-col>
<c-col class="d-flex align-items-center">
{{startDate() | date}} {{ startDate() ? '->' : ''}} {{endDate() | date}}
</c-col>
</c-row>
Weeks
Set selectionType to week to select a range of whole weeks, and add showWeekNumber to show the week numbers in the calendar. Since 5.7.38 the input shows a week as 2025W07, numbered as its row in the week number column, and reads that text back.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-weeks',
templateUrl: './date-range-picker-weeks.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerWeeksComponent {
readonly startDate = new Date(2025, 1, 10);
readonly endDate = new Date(2025, 2, 23);
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker locale="en-US" selectionType="week" showWeekNumber />
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[startDate]="startDate"
locale="en-US"
selectionType="week"
showWeekNumber
/>
</c-col>
</c-row>Months
Set selectionType to month to select a range of whole months. Since 5.7.38 the input shows a month as 2022-08 and reads that text back.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-months',
templateUrl: './date-range-picker-months.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerMonthsComponent {
readonly startDate = new Date(2022, 7, 1);
readonly endDate = new Date(2023, 4, 31);
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker locale="en-US" selectionType="month" />
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[startDate]="startDate"
locale="en-US"
selectionType="month"
/>
</c-col>
</c-row>Years
Set selectionType to year to select a range of whole years. Since 5.7.38 the input shows a year as 2022 and reads that text back.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-years',
templateUrl: './date-range-picker-years.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerYearsComponent {
readonly startDate = new Date(2022, 0, 1);
readonly endDate = new Date(2028, 11, 31);
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker locale="en-US" selectionType="year" />
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[startDate]="startDate"
locale="en-US"
selectionType="year"
/>
</c-col>
</c-row>Sizing
Set heights using size property like size="lg" and size="sm".
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-sizing',
templateUrl: './date-range-picker-sizing.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerSizingComponent {}<c-row class="mb-4">
<c-col lg="6">
<c-date-range-picker size="lg" />
</c-col>
</c-row>
<c-row>
<c-col lg="4">
<c-date-range-picker size="sm" />
</c-col>
</c-row>Disabled
Add the disabled boolean attribute on an input to give it a grayed out appearance and remove pointer events.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-disabled',
templateUrl: './date-range-picker-disabled.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerDisabledComponent {}<c-row>
<c-col lg="6">
<c-date-range-picker disabled />
</c-col>
</c-row>Readonly
Add the inputReadOnly boolean attribute to prevent modification of the input value.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-readonly',
templateUrl: './date-range-picker-readonly.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerReadonlyComponent {}<c-row>
<c-col lg="6">
<c-date-range-picker inputReadOnly />
</c-col>
</c-row>Preview date on hover
Added in v5.7.38By default, the date range picker shows the hovered or focused calendar date in the start input until a start date is picked, and then in the end input. To disable this feature, set [previewDateOnHover]="false".
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-preview-date-on-hover',
templateUrl: './date-range-picker-preview-date-on-hover.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerPreviewDateOnHoverComponent {}<c-row>
<c-col class="mb-3 mb-sm-0" sm="6">
<div class="form-label">With preview (default)</div>
<c-date-range-picker locale="en-US" />
</c-col>
<c-col sm="6">
<div class="form-label">Without preview</div>
<c-date-range-picker [previewDateOnHover]="false" locale="en-US" />
</c-col>
</c-row>Disabled dates
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-disabled-dates',
templateUrl: './date-range-picker-disabled-dates.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerDisabledDatesComponent {
public calendarDate = new Date(2022, 2, 1);
public disabledDates = [
[new Date(2022, 2, 4), new Date(2022, 2, 7)], // range of dates that cannot be selected
new Date(2022, 2, 16), // single date that cannot be selected
new Date(2022, 3, 16),
[new Date(2022, 4, 2), new Date(2022, 4, 8)]
];
public maxDate = new Date(2022, 5, 0);
public minDate = new Date(2022, 0, 1);
dateFilter = (date: Date | null): boolean => {
const day = date?.getDay();
return day !== 0;
};
}<c-row>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="calendarDate"
[dateFilter]="dateFilter"
[disabledDates]="disabledDates"
[maxDate]="maxDate"
[minDate]="minDate"
locale="de-AT"
/>
</c-col>
</c-row>
Disabling weekends
Pass a function to dateFilter to decide which dates can be picked: it receives a date and returns true when the date is selectable. To disable weekends, return false for Sunday (0) and Saturday (6). A range cannot include a date that dateFilter rules out, so here a range stays within the working days of one week.
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-disabling-weekends',
templateUrl: './date-range-picker-disabling-weekends.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerDisablingWeekendsComponent {
readonly disableWeekends = (date: Date): boolean => {
const day = date.getDay();
return day !== 0 && day !== 6;
};
}<c-row>
<c-col lg="6">
<c-date-range-picker [dateFilter]="disableWeekends" locale="en-US" />
</c-col>
</c-row>Custom ranges
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-custom-ranges',
templateUrl: './date-range-picker-custom-ranges.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerCustomRangesComponent {
public customRanges = {
Today: [new Date(), new Date()],
Yesterday: [
new Date(new Date().setDate(new Date().getDate() - 1)),
new Date(new Date().setDate(new Date().getDate() - 1))
],
'Last 7 Days': [new Date(new Date().setDate(new Date().getDate() - 6)), new Date(new Date())],
'Last 30 Days': [new Date(new Date().setDate(new Date().getDate() - 29)), new Date(new Date())],
'This Month': [new Date(new Date().setDate(1)), new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0)],
'Last Month': [
new Date(new Date().getFullYear(), new Date().getMonth() - 1, 1),
new Date(new Date().getFullYear(), new Date().getMonth(), 0)
]
};
}<c-row>
<c-col lg="6">
<c-date-range-picker
[ranges]="customRanges"
rangesButtonsColor="primary"
/>
</c-col>
</c-row>Non-english locale
The inputs read typed dates in the numeric format they show for the locale, with ., /, - or a space between the parts. Since 5.7.40 they also read the digits of the locale and, in th-TH, the Buddhist year, and the spaces and the closing mark of the format may be left out. In other calendars, such as Persian (fa-IR) or the Japanese eras (ja-JP-u-ca-japanese), and in a format that shows an era, typed text is reported as datePickerParse: give inputDateFormat with inputDateParse to read it, or set inputReadOnly.
Auto
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-auto',
templateUrl: './date-range-picker-auto.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerAutoComponent {}<c-row>
<c-col lg="6">
<c-date-range-picker />
</c-col>
</c-row>Chinese
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-chinese',
templateUrl: './date-range-picker-chinese.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerChineseComponent {}<c-row>
<c-col lg="6">
<c-date-range-picker
[placeholder]="['入住日期', '退房日期']"
locale="zh-Hant"
weekdayFormat="narrow"
/>
</c-col>
</c-row>Japanese
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-japanese',
templateUrl: './date-range-picker-japanese.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerJapaneseComponent {}<c-row>
<c-col lg="6">
<c-date-range-picker
[placeholder]="['日付を選択', '終了日']"
locale="ja"
/>
</c-col>
</c-row>Korean
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-korean',
templateUrl: './date-range-picker-korean.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerKoreanComponent {
dayFormat = (date: Date) => date.getDate();
}<c-row>
<c-col lg="6">
<c-date-range-picker
[dayFormat]="dayFormat"
[placeholder]="['날짜 선택', '종료일']"
locale="ko"
navYearFirst
/>
</c-col>
</c-row>
Right to left support
RTL support is built-in and can be explicitly controlled through the $enable-rtl variables in scss.
Hebrew
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-hebrew',
templateUrl: './date-range-picker-hebrew.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerHebrewComponent {}<c-row>
<c-col lg="6">
<div dir="rtl">
<c-date-range-picker
[placeholder]="['תאריך סיום', 'בחר תאריך']"
locale="he-IL"
weekdayFormat="narrow"
/>
</div>
</c-col>
</c-row>Persian
import { Component } from '@angular/core';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-persian',
templateUrl: './date-range-picker-persian.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerPersianComponent {}<c-row>
<c-col lg="6">
<div dir="rtl">
<c-date-range-picker
inputReadOnly
[placeholder]="['تاریخ پایان', 'تاریخ شروع']"
locale="fa-IR"
weekdayFormat="narrow"
/>
</div>
</c-col>
</c-row>
Custom formats
Use inputDateFormat to write the date into the input in a format of your choice, and inputDateParse to read the typed text back into a Date. Unlike format, which needs a locale with its Angular locale data registered (registerLocaleData) and makes the input read-only, these keep the input editable. The examples below use the format and parse functions from date-fns, with the English and Spanish patterns 'MMMM dd, yyyy' and 'yyyy MMMM dd'.
import { format, parse } from 'date-fns';
import { es } from 'date-fns/locale';import { Component } from '@angular/core';
import { format, parse } from 'date-fns';
import { es } from 'date-fns/locale';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-custom-formats',
templateUrl: './date-range-picker-custom-formats.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerCustomFormatsComponent {
readonly startDate = new Date(2022, 7, 3);
readonly endDate = new Date(2022, 7, 17);
readonly formatEn = (date: Date) => format(date, 'MMMM dd, yyyy');
readonly parseEn = (value: string | Date) => parse(String(value), 'MMMM dd, yyyy', new Date());
readonly formatEs = (date: Date) => format(date, 'yyyy MMMM dd', { locale: es });
readonly parseEs = (value: string | Date) => parse(String(value), 'yyyy MMMM dd', new Date(), { locale: es });
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEn"
[inputDateParse]="parseEn"
[startDate]="startDate"
locale="en-US"
/>
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEs"
[inputDateParse]="parseEs"
[placeholder]="['Fecha de inicio', 'Fecha de fin']"
[startDate]="startDate"
locale="es-ES"
/>
</c-col>
</c-row>Weeks
Set selectionType to week and give inputDateFormat and inputDateParse a week-based pattern, such as 'Io RRRR' (the ISO week number and its year). Add showWeekNumber to show the week numbers in the calendar.
import { Component } from '@angular/core';
import { format, parse } from 'date-fns';
import { es } from 'date-fns/locale';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-custom-formats-weeks',
templateUrl: './date-range-picker-custom-formats-weeks.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerCustomFormatsWeeksComponent {
readonly startDate = new Date(2022, 2, 7);
readonly endDate = new Date(2022, 3, 3);
readonly formatEn = (date: Date) => format(date, 'Io RRRR');
readonly parseEn = (value: string | Date) => parse(String(value), 'Io RRRR', new Date());
readonly formatEs = (date: Date) => format(date, 'Io RRRR', { locale: es });
readonly parseEs = (value: string | Date) => parse(String(value), 'Io RRRR', new Date(), { locale: es });
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEn"
[inputDateParse]="parseEn"
[startDate]="startDate"
locale="en-US"
selectionType="week"
showWeekNumber
/>
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEs"
[inputDateParse]="parseEs"
[placeholder]="['Fecha de inicio', 'Fecha de fin']"
[startDate]="startDate"
locale="es-ES"
selectionType="week"
showWeekNumber
/>
</c-col>
</c-row>Months
Set selectionType to month and give inputDateFormat and inputDateParse a month pattern, such as 'MMM yyyy'.
import { Component } from '@angular/core';
import { format, parse } from 'date-fns';
import { es } from 'date-fns/locale';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-custom-formats-months',
templateUrl: './date-range-picker-custom-formats-months.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerCustomFormatsMonthsComponent {
readonly startDate = new Date(2022, 7, 1);
readonly endDate = new Date(2023, 3, 30);
readonly formatEn = (date: Date) => format(date, 'MMM yyyy');
readonly parseEn = (value: string | Date) => parse(String(value), 'MMM yyyy', new Date());
readonly formatEs = (date: Date) => format(date, 'MMM yyyy', { locale: es });
readonly parseEs = (value: string | Date) => parse(String(value), 'MMM yyyy', new Date(), { locale: es });
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEn"
[inputDateParse]="parseEn"
[startDate]="startDate"
locale="en-US"
selectionType="month"
/>
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEs"
[inputDateParse]="parseEs"
[placeholder]="['Fecha de inicio', 'Fecha de fin']"
[startDate]="startDate"
locale="es-ES"
selectionType="month"
/>
</c-col>
</c-row>Years
Set selectionType to year and give inputDateFormat and inputDateParse a year pattern, such as 'yy'.
import { Component } from '@angular/core';
import { format, parse } from 'date-fns';
import { es } from 'date-fns/locale';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-custom-formats-years',
templateUrl: './date-range-picker-custom-formats-years.component.html',
imports: [RowComponent, ColComponent, DateRangePickerComponent]
})
export class DateRangePickerCustomFormatsYearsComponent {
readonly startDate = new Date(2022, 0, 1);
readonly endDate = new Date(2024, 11, 31);
readonly formatEn = (date: Date) => format(date, 'yy');
readonly parseEn = (value: string | Date) => parse(String(value), 'yy', new Date());
readonly formatEs = (date: Date) => format(date, 'yy', { locale: es });
readonly parseEs = (value: string | Date) => parse(String(value), 'yy', new Date(), { locale: es });
}<c-row>
<c-col class="mb-3 mb-lg-0" lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEn"
[inputDateParse]="parseEn"
[startDate]="startDate"
locale="en-US"
selectionType="year"
/>
</c-col>
<c-col lg="6">
<c-date-range-picker
[calendarDate]="startDate"
[endDate]="endDate"
[inputDateFormat]="formatEs"
[inputDateParse]="parseEs"
[placeholder]="['Fecha de inicio', 'Fecha de fin']"
[startDate]="startDate"
locale="es-ES"
selectionType="year"
/>
</c-col>
</c-row>Accessibility
Added in v5.7.38- The calendar button is named by
ariaPickerLabeland, once both ends are set, the picked range (Toggle calendar, Monday, January 5 – Friday, January 9, 2026), so a screen reader reads the pick when focus comes back to it. The dates followlocale: set it to the language of the label. - The clear button is named by
ariaCleanerLabel. With a value, it shows while focus is in the field and keeps its place while hidden;[cleaner]="false"gives that place back to the inputs in a narrow layout. - Closing the calendar from inside (
Escape, a pick withcloseOnSelect, a close button in the footer) returns focus to the input it was opened from, or to the calendar button that opened it. After a touch an editable input does not get it back, so the on-screen keyboard stays closed; the calendar button takes it when there is one.
Keyboard behavior
| Key | Action |
|---|---|
Tab | Start input, end input, clear button, calendar button |
Enter / Space on the calendar button | Open or close the calendar |
Alt + ArrowDown (Option on macOS) in an input | Open the calendar and move focus into it |
Enter / Space on a date | Pick it; with closeOnSelect the calendar closes once the range is complete |
Escape | Close the calendar |
Enter / Space on the clear button | Clear the dates, focus the start input |
| Other keys in the calendar | See Calendar |
Forms
Angular handles user input through reactive, template-driven and signal forms. CoreUI Date Range Picker supports all three.
The control is marked touched when the user leaves the date range picker (the focus moves to another element or a click lands outside it) or both ends are set while its calendar is open; with updateOn: 'blur' that also commits the value.
Validation
Added in v5.7.40Text the picker cannot turn into an allowed date stays in its input with aria-invalid="true", that end becomes null and the control reports (the start first when both fail):
{ datePickerParse: { part: 'start' | 'end', reason: 'parse' | 'disabled' | 'order', text: string } }parse: not a date (an invalid date from the page gives an emptytext)disabled: outsideminDate/maxDate, indisabledDatesor rejected bydateFilterorder: an end before the start or without one
A start without a date clears the end, a typed start after the end begins a new range. Set the value and disabled through the form or through the inputs, not both, and give an end from the page its start.
[valid]="false" sets aria-invalid="true" on both inputs and shows the invalid icon on the end input only. aria-describedby on c-date-range-picker, as a static attribute or bound with [aria-describedby], moves to both inputs, so the feedback is read with them; [attr.aria-describedby] does not reach the inputs.
Reactive
import { JsonPipe } from '@angular/common';
import { Component, OnInit, signal } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-reactive',
templateUrl: './date-range-picker-reactive.component.html',
imports: [RowComponent, ColComponent, ReactiveFormsModule, DateRangePickerComponent, JsonPipe]
})
export class DateRangePickerReactiveComponent implements OnInit {
startDate = new Date();
endDate = new Date();
formGroup!: FormGroup;
readonly #toLocaleDateString = signal('');
get toLocaleDateString() {
return this.#toLocaleDateString();
}
ngOnInit(): void {
const startDate = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate());
const endDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() + 6);
const dateRange = { startDate, endDate };
this.formGroup = new FormGroup({
dateRangePicker: new FormControl(dateRange, { nonNullable: false })
});
this.formGroup.valueChanges.subscribe((value) => {
this.#toLocaleDateString.set(
value.dateRangePicker.startDate?.toLocaleDateString() +
' -> ' +
value.dateRangePicker.endDate?.toLocaleDateString()
);
});
}
}<c-row>
<c-col lg="6">
<form [formGroup]="formGroup">
<c-date-range-picker formControlName="dateRangePicker" />
</form>
</c-col>
</c-row>
<br>
Form value: {{ formGroup.value | json }}
<br>
dateRangePicker value: {{ toLocaleDateString }}Template-driven
import { DatePipe, JsonPipe } from '@angular/common';
import { Component, OnInit, signal } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ColComponent, DateRangePickerComponent, RowComponent } from '@coreui/angular';
@Component({
selector: 'docs-date-range-picker-template-driven',
templateUrl: './date-range-picker-template-driven.component.html',
imports: [RowComponent, ColComponent, ReactiveFormsModule, FormsModule, DateRangePickerComponent, JsonPipe, DatePipe]
})
export class DateRangePickerTemplateDrivenComponent implements OnInit {
readonly value = signal<{ startDate: Date; endDate: Date } | null>(null);
ngOnInit(): void {
const date = new Date();
const startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 6);
const endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
this.value.set({ startDate, endDate });
}
}<c-row>
<c-col lg="6">
<form #form="ngForm">
<c-date-range-picker [(ngModel)]="value" name="dateRangePicker" />
</form>
</c-col>
</c-row>
<br />
dateRangePicker value: {{ form.value['dateRangePicker'] | json }}
<br />
startDate: {{ $safeNavigationMigration(form.value['dateRangePicker']?.startDate) | date: 'fullDate' }} -> endDate:
{{ $safeNavigationMigration(form.value['dateRangePicker']?.endDate) | date: 'fullDate' }}
<br />Signal forms
import { DatePipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import { form, FormField, FormRoot, validate } from '@angular/forms/signals';
import { ColComponent, DateRangePickerComponent, FormFeedbackComponent, RowComponent } from '@coreui/angular';
interface DateRangePickerFormModel {
dateRange: { startDate: Date | null; endDate: Date | null } | null;
}
@Component({
selector: 'docs-date-range-picker-signal-forms',
templateUrl: './date-range-picker-signal-forms.component.html',
imports: [ColComponent, DatePipe, DateRangePickerComponent, FormFeedbackComponent, FormField, FormRoot, RowComponent]
})
export class DateRangePickerSignalFormsComponent {
readonly dateRangeModel = signal<DateRangePickerFormModel>({ dateRange: null });
readonly dateRangeForm = form(this.dateRangeModel, (schemaPath) => {
validate(schemaPath.dateRange, ({ value }) =>
value()?.startDate && value()?.endDate ? undefined : { kind: 'range', message: 'Pick the start and end dates' }
);
});
}@let ctrl = dateRangeForm.dateRange();
<c-row>
<c-col lg="6">
<form [formRoot]="dateRangeForm">
<c-date-range-picker [formField]="dateRangeForm.dateRange" [valid]="ctrl.touched() ? !ctrl.invalid() : undefined" />
@let error = ctrl.touched() ? ctrl.errors()[0] : undefined;
@if (error) {
<c-form-feedback [valid]="false">
{{ error.kind === 'datePickerParse' ? 'Enter dates the picker allows' : error.message }}
</c-form-feedback>
}
</form>
</c-col>
</c-row>
<br>
startDate: {{ ctrl.value()?.startDate | date: 'fullDate' }} -> endDate: {{ ctrl.value()?.endDate | date: 'fullDate' }}API reference
DateRangePicker Module
import {
DateRangePickerModule,
DropdownModule,
SharedModule
} from '@coreui/angular';
@NgModule({
imports: [
DateRangePickerModule,
DropdownModule,
SharedModule
]
})
export class AppModule() { }c-date-range-picker
component
import { DateRangePickerComponent } from '@coreui/angular-pro'