I am using the latest Angular Material 5.0.0-rc0
in my Angular 5 app. I am trying to select a range of dates with the datepicker
provided with Angular
There's an open issue at the github page.
https://github.com/angular/material2/issues/4763
In Angular-Blog, there's a note for this too (look at the end).
https://blog.angular.io/taking-advantage-of-the-angular-material-datepicker-237e80fa14b3
The Angular version of the Angular UI Bootstrap library has a date range selector, you can check out that. I am using it in my projects.
https://ng-bootstrap.github.io/#/components/datepicker/examples
Now available in Angular Material v10.0.1 or more
https://material.angular.io/components/datepicker/overview#date-range-selection
Recommend to check out Saturn Material range Datepicker. Have a look also at their demo page. It is a full Material UX with built-in support for your existing Material theme.
You can install it with npm install saturn-datepicker
. See their Github page for full integration instructions.
Markup looks like this:
<mat-form-field>
<input matInput
placeholder="Choose a date"
[satDatepicker]="picker"
[value]="date">
<sat-datepicker #picker [rangeMode]="true"></sat-datepicker>
<sat-datepicker-toggle matSuffix [for]="picker"></sat-datepicker-toggle>
</mat-form-field>
And here is what it ends up looking like on the page:
In the mean time you could just have two date pickers. One for the start date and one for the end date. Something like this:
<mat-form-field> //start date datepicker
<input matInput [min]="minDate" [max]="maxDate" [formControl]="startDate" [matDatepicker]="picker" placeholder="Choose a start date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="minDate"></mat-datepicker>
</mat-form-field>
<mat-form-field> //end date datepicker
<input matInput [min]="startDate" [max]="maxDate" [formControl]="endDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
</mat-form-field>
You could then have some where if they change the endDate
to something before the startDate
it shows them an error or resets the startDate
It is totally possible to do it but not directly with mat-datepicker component. Actually, mat-datepicker uses mat-menu component to display a mat-calendar component.
To perform what you ask, you could use something like below.
In your component.html file
<mat-menu #startDateRangeMenu="matMenu">
<mat-calendar
#calendar
(click)="$event.stopPropagation()"
(selectedChange)="toggleStartDateDate($event, calendar)"
[dateClass]="isStartDateDateSelected()">
</mat-calendar>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="startDateRangeMenu">
{{'startDate' | translate}}
</button>
In your .ts file
isStartDateSelected() {
return (date: Date): MatCalendarCellCssClasses => {
const dateMoment = moment(date);
let startDate;
let endDate;
if (this.startDateAfter) {
startDate = moment(this.startDateAfter);
}
if (this.startDateBefore) {
endDate = moment(this.startDateBefore);
}
if (startDate && endDate && dateMoment.isBetween(startDate, endDate, 'days', '[]')) {
return 'date-selected';
} else if (startDate && dateMoment.isSame(startDate)) {
return 'date-selected';
} else if (moment().startOf('day').isSame(moment(date).startOf('day'))) {
return 'today';
}
return;
};
}
toggleStartDateDate(date: any, calendar: any) {
const dateString = moment(date).format('YYYY-MM-DD');
if (this.selectStartDateType === 'startDateAfter') {
this.startDateAfter = dateString;
this.startDateBefore = dateString;
this.selectStartDateType = 'startDateBefore';
} else {
if (moment(date).isBefore(moment(this.startDateAfter))) {
this.startDateAfter = dateString;
this.startDateBefore = dateString;
this.selectStartDateType = 'startDateBefore';
} else {
this.startDateBefore = dateString;
this.selectStartDateType = 'startDateAfter';
}
}
calendar.updateTodaysDate();
}
In your .css file
::ng-deep .date-selected .mat-calendar-body-cell-content {
background-color: #17a2b8;
color: white;
}
::ng-deep .date-selected.mat-calendar-body-cell:hover .mat-calendar-body-cell-content {
background-color: #17a2b8 !important;
}