OpenSource Programming Tips & Trick Utilities

Angular Material Date Range Picker with Custom Range Presets

This feature enhances the functionality of selecting date ranges by providing a date picker with the ability to use custom range presets.

by Vignesh P on July 18, 2023

A date range picker provides a way for the user not only to pick one date in an input field, but two dates, which together build a time range. There are many use cases for this kind of component. One example would be the selection of a vacation period in a vacation planner app. In Angular, using Material Date Range Picker we can implement date range selection. Documentation and examples can be found in a sub-section of the date picker section of the official Angular Material page.
Angular Material Date Range Picker
After clicking on the calendar symbol on the right side of the form field, the picker is opened, showing the current day. Its toolbar on the top enables us to switch between day, month and year view.
Angular Material date range picker: day, month and year views
Custom Ranges :
It’s a common use case to have pre-defined ranges like “last month” or “this week” which can be selected to set the date range. There are a couple of libraries out there, e.g. ngx-daterangepicker-material, that provide this functionality. Unfortunately, the Angular Material date range picker does not.
Material Date picker with Custom Range Presets
So, what to do if we must have that “Last 7 Days” button, but want to use Material’s date range picker? Of course, we could add an additional menu button to our form field, that opens yet another overlay to choose the preset. But this would not be very intuitive for users that are used to pickers with custom range selection (and probably would look like not very well). We want to integrate this directly into the picker component itself. Searching through the API docs, we can find that there is one way to customize the picker component: the Customizing the calendar header section describes how the picker’s header area can be replaced by a custom component.

Implementation of a Custom Header

<!-- date-range-picker.component.html -->
<mat-date-range-picker #picker [calendarHeaderComponent]="CustomHeaderComponent"></mat-date-range-picker>

To implement custom header, we can pass Custom Header Component to calendarHeaderComponent prop. In the custom header component, to use existing material date picker header, we can use MatCalendarHeaderComponent by adding mat-calendar-header and can inject instance of calendar and date range picker.


Implementation of custom range panel to custom header

So far, we didn’t add something new to the Material custom header example. Time to actually implement the custom range buttons! The idea is, to add a panel to the left of the picker that contains all selectable ranges. When we’re done it will look like this:

Date range picker with our custom range panel to the left

<!--custom.header.component.html

Here is the code add custom range panel to custom header. -->

<app-custom-range-panel [customPresets]="pickerService.customPresets"></app-custom-range-panel>
<mat-calendar-header></mat-calendar-header>
To add custom presets, we are passing the presets list to the custom range panel from custom header component. Because different picker has different presets and in custom header component, we are injecting our DateRangePicker service to the CustomHeader component.
<!-- date-range-picker.service.ts -->
@Injectable()
export class DateRangePickerService{
    public customPresets:string[]=[];
}
In our DateRangePicker service, we are declared the variable to store custom presets. Value of customPresets has been assigned from the date range picker component. This service provided within date range picker component, so that different date range picker component has different service instance.
<!-- date-range-picker.component.ts -->
export class DateRangePickerComponent{
@Input() customPresets:string[]=[];

constructor(public pickerService:DateRangePickerService){}
    ngOnInit(){
        this.pickerService.customPresets = this.customPresets;
    }
}
Here we also implemented disable apply button when start or end date is not selected. For this implementation we declared BehaviorSubject of rxjs in the service and set the value in the custom header component. You can view the working solution on Stackblitz. By using angular material date range picker, we can get date range input from user. But if we need to give some custom presets for better user experience, we have to customize or extend the functionality of the control. For this implementation, the control provides option to customize the header. By using this, we can add custom presets component via custom header.

Leave a Reply

%d bloggers like this: