Angular Range Date Filter with Preset Ranges
Get started with this exampleUsage
theme: 'ios' You can turn auto theming on and let it decide based on the platform.
Usage
themeVariant: 'light' You can turn auto dark mode on based on system settings.
Usage
touchUi: true
// touch interaction is enabled Use touch interaction on mobile or pointer interaction on desktop.
Usage
locale: localeEn Selecting the locale loads the localized settings and the translated UI text.
Date Filter with Preset Ranges
When building a date filtering UI a date range picker is essential. On top of being able to select custom start and end dates presets can be very helpful and provide a nice productivity boost. A more advanced filtering experience can be created in a couple of steps:
- Custom popup with an inline calendar - Create a custom popup and place an inline date picker with start/end selection
- Select with common presets - Populate a dropdown with values like Today, Yesterday, Last week, Last month, Last 7 days, Last 30 days
- Inputs for typing dates - Adding two inputs next to the range picker enables users to type in a date rather than solely relying on manual selection
- Make it fully responsive - Use the
responsiveapi to customize the desktop experience - dropdown with inputs for typing - and the mobile experience - touch optimized interface
Demo
Code
import { CommonModule } from '@angular/common';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
formatDate,
MbscDatepickerOptions,
MbscDateType,
MbscInput,
MbscModule,
MbscPopup,
MbscPopupOptions,
MbscSelectData,
MbscSelectOptions,
options,
setOptions ,
} from '@mobiscroll/angular';
setOptions({
locale: ,
theme: ' ',
themeVariant: ' '
});
const now = new Date();
const day = now.getDay();
const monday = now.getDate() - day + (day === 0 ? -6 : 1);
const startDate = '2026-11-06T00:00';
const endDate = '2026-11-12T00:00';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: true,
imports: [CommonModule, FormsModule, MbscModule],
})
export class AppComponent implements OnInit, AfterViewInit {
@ViewChild('popup', { static: false })
popup!: MbscPopup;
@ViewChild('input', { static: false })
input!: MbscInput;
inputElm!: HTMLElement;
dateInput = '';
selected = 'custom';
selectedDate: MbscDateType[] = [startDate, endDate];
disableInput = false;
respPopup: Record<string, MbscPopupOptions & { breakpoint?: number }> = {
xsmall: {
display: 'bottom',
touchUi: true,
buttons: [
{
text: 'Apply',
handler: () => {
this.changeInputValue(this.selectedDate[0] as string, (this.selectedDate[1] || this.selectedDate[0]) as string);
this.popup.close();
},
},
'cancel',
],
},
custom: {
breakpoint: 559,
buttons: [],
display: 'anchored',
anchorAlign: 'start',
touchUi: false,
scrollLock: false,
showArrow: false,
maxWidth: 920,
},
};
respSelect = {
xsmall: {
touchUi: true,
},
small: {
touchUi: false,
},
};
myData: MbscSelectData[] = [
{
value: 'custom',
text: 'Custom',
},
{
value: 'today',
text: 'Today',
},
{
value: 'yesterday',
text: 'Yesterday',
},
{
value: 'last-week',
text: 'Last week',
},
{
value: 'last-month',
text: 'Last month',
},
{
value: 'last-7-days',
text: 'Last 7 days',
},
{
value: 'last-30-days',
text: 'Last 30 days',
},
];
selectOptions: MbscSelectOptions = {
responsive: {
xsmall: {
touchUi: true,
},
small: {
touchUi: false,
},
},
onChange: (args) => {
const s = args.value;
if (s === 'custom') {
this.disableInput = false;
} else {
this.disableInput = true;
switch (s) {
case 'today':
this.selectedDate = ['2021-09-15T00:00', '2021-09-15T00:00'];
break;
case 'yesterday':
this.selectedDate = ['2021-09-14T00:00', '2021-09-14T00:00'];
break;
case 'last-week':
this.selectedDate = [
new Date(now.getFullYear(), now.getMonth(), monday - 7),
new Date(now.getFullYear(), now.getMonth(), monday - 1),
];
break;
case 'last-month':
this.selectedDate = ['2021-08-01T00:00', '2021-08-31T00:00'];
break;
case 'last-7-days':
this.selectedDate = ['2021-09-09T00:00', '2021-09-15T00:00'];
break;
case 'last-30-days':
this.selectedDate = ['2021-08-17T00:00', '2021-09-15T00:00'];
break;
default:
break;
}
}
this.selected = s;
},
};
calendarOptions: MbscDatepickerOptions = {
controls: ['calendar'],
select: 'range',
display: 'inline',
showRangeLabels: false,
pages: 'auto',
returnFormat: 'iso8601',
showOnClick: false,
showOnFocus: false,
onChange: () => {
this.disableInput = false;
},
};
inputClick(): void {
this.popup.open();
}
changeInputValue(start: string, end: string): void {
const locale = options.locale || {};
const dateFormat = locale.dateFormat || 'DD/MM/YYYY';
this.dateInput = formatDate(dateFormat, new Date(start)) + ' - ' + formatDate(dateFormat, new Date(end));
}
applyClick(): void {
const date = this.selectedDate;
this.changeInputValue(date[0] as string, (date[1] || date[0]) as string);
this.popup.close();
}
cancelClick(): void {
this.popup.close();
}
ngOnInit(): void {
this.changeInputValue(startDate, endDate);
}
ngAfterViewInit(): void {
setTimeout(() => {
this.inputElm = this.input.nativeElement;
});
}
}
<mbsc-page>
<div class="mbsc-form-group">
<mbsc-input #input [(ngModel)]="dateInput" inputStyle="box" labelStyle="stacked" (click)="inputClick()"></mbsc-input>
</div>
<mbsc-popup class="demo-date-filtering-popup" [anchor]="inputElm" [responsive]="respPopup" #popup>
<div class="mbsc-grid mbsc-no-padding">
<div class="mbsc-row">
<div class="mbsc-col-sm-4 mbsc-push-sm-8 demo-date-filtering-dates">
<div class="demo-date-filtering-inputs">
<mbsc-select
[(ngModel)]="selected"
[data]="myData"
label="Date range"
inputStyle="box"
labelStyle="stacked"
[options]="selectOptions"
></mbsc-select>
<mbsc-input #start label="Start" inputStyle="box" labelStyle="stacked" [disabled]="disableInput"></mbsc-input>
<mbsc-input #end label="End" inputStyle="box" labelStyle="stacked" [disabled]="disableInput"></mbsc-input>
</div>
<div class="demo-date-filtering-desktop-buttons mbsc-button-group-justified">
<mbsc-button class="apply-button" (click)="applyClick()">Apply</mbsc-button>
<mbsc-button class="cancel-button" (click)="cancelClick()">Cancel</mbsc-button>
</div>
</div>
<div class="mbsc-col-sm-8 mbsc-pull-sm-4">
<mbsc-datepicker [(ngModel)]="selectedDate" [startInput]="start" [endInput]="end" [options]="calendarOptions"></mbsc-datepicker>
</div>
</div>
</div>
</mbsc-popup>
</mbsc-page>
.demo-date-filtering-popup .mbsc-ios.mbsc-datepicker-inline {
border: none;
border-radius: 4px;
overflow: hidden;
}
.demo-date-filtering-popup .mbsc-textfield-wrapper-box {
margin-top: 0;
margin-right: 0;
}
.demo-date-filtering-dates {
display: flex;
flex-direction: column;
}
.demo-date-filtering-inputs {
flex: 1;
}
.demo-date-filtering-desktop-buttons.mbsc-button-group-justified,
.demo-date-filtering-desktop-buttons.mbsc-button-group-justified button {
margin-bottom: 0;
}
@media (max-width: 575px) {
.demo-date-filtering-desktop-buttons {
display: none;
}
.demo-date-filtering-popup .mbsc-textfield-wrapper-box {
margin-left: 0;
}
}