Angular 12 Material Datepicker Range Selection From To Dates with Validation

In this Angular Material tutorial, we’re going to discuss how to implement Material Datepicker with Range selection for From-To dates with required validation in Angular 12 application.

Angular Material Datepicker component can be easily implemented by importing the MatDatepickerModule and MatNativeDateModule or MatMomentDateModule APIs as discussed previous post with custom Date parse formats.

In the template, we simply add the <mat-datepicker/> component to create a datepicker. In this article, we’re going to discuss how to add a Datepicker with Range selection with validation, where a user can select a start date and to or end date.

 

The validation part will check if From and To dates are selected properly in the Datepicker.

Let’s start the implementation…

 

Setup Angular CLI

First, install or update the Angular CLI tool to the latest version by running the below NPM command

$ npm install -g @angular/cli

You can check the version of Angular currently installed

$ ng --version
Angular CLI: 10.0.3
Node: 12.15.0
OS: win32 x64

 

Create a New Angular Application

Run the following ng command to create a new Angular project

$ ng new angular-mat-datepicker-range
# ? Would you like to add Angular routing? No
# ? Which stylesheet format would you like to use? SCSS

Enter the project directory

$ cd angular-mat-datepicker-range

Run the application

$ ng serve --open

 

Install Material Package

After creating the Angular project, install the Material UI library by hitting the following ng command

$ ng add @angular/material
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink      
? Set up global Angular Material typography styles? No  
? Set up browser animations for Angular Material? Yes

 

Using Datepicker Modules

There is a number of Modules available in the Material package, so we need to import the required modules which will be used in the application.

For using the Material Datepicker, we’ll import the MatDatepickerModule. The Datepicker also needs an Adapter to work with Javascript Date methods. There are three options available for Date Adapters.

  • MatNativeDateModule: Uses native Javascript Date methods.
  • MatMomentDateModule: Uses Moment.js library to work with Date methods.
  • Custom DateAdapter: We can also create our own customized Date adapter.

For the current to the tutorial, we’re going to use the MatNativeDateModule, as we’re not discussing custom Date Format using Moment. If you want to learn more about how to show a custom date format in Material datepicker visit this post.

 

Import Datepicker and Adapter in App Module

After installing the Material and Moment package, import the MatDatepicker and MatNativeDateModule. The MatInputModule module is also required to use Input control and FormsModule to use [(ngModel)].

so the app.module.ts file will look like this:

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';

import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,

    MatDatepickerModule,
    MatNativeDateModule,

    MatInputModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

Adding Material Datepicker with Range Selection

To enable a user to select two for From and To, we need to wrap two <input/> inside the mat-date-range-input component.

<mat-date-range-input>
     <input matStartDate placeholder="Start date">
     <input matEndDate placeholder="End date">
</mat-date-range-input>

 

Then add the mat-date-range-picker component below it. This will create a slightly different calendar picker with a range selection feature.

<mat-form-field>

    <mat-label>Enter Session Period</mat-label>
    <mat-date-range-input [rangePicker]="picker">
      <input matStartDate placeholder="From Date">
      <input matEndDate placeholder="To Date">
    </mat-date-range-input>

    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>

</mat-form-field>

Here we’re connecting the Datepicker calendar popup with [rangePicker] through the template variable #picker.

 

 

Adding Reactive Form Validation in Material Datepicker Range Selection

To add validation in a real-world application, we have wrapped the Datepicker with a <form/> having [formGroup] and (ngSubmit) event handler.

<form [formGroup]="dateRangeForm" (ngSubmit)="onFormSubmit()">
...
</form>

 

Now add a Material Datepicker for Range selection with <input/> controls having formControlName property

<mat-date-range-input [rangePicker]="picker">
        <input matStartDate placeholder="From Date" required formControlName="fromDate">
        <input matEndDate placeholder="To Date" required formControlName="toDate">
</mat-date-range-input>

Also, add mat-error components to show error messages for showing required and invalid notification messages to users.

<!-- Invalid Date Messages -->
<mat-error *ngIf="dateRangeForm.controls.fromDate.hasError('matStartDateInvalid')">Invalid start date</mat-error>
<mat-error *ngIf="dateRangeForm.controls.toDate.hasError('matEndDateInvalid')">Invalid end date</mat-error>

<!-- Required Date Messages -->
<mat-error *ngIf="dateRangeForm.controls.fromDate.errors?.required">From Date Required</mat-error>
<mat-error *ngIf="dateRangeForm.controls.toDate.errors?.required">To Date Required</mat-error>

 

Finally, the complete form template will look like this:

<form [formGroup]="dateRangeForm" (ngSubmit)="onFormSubmit()">

    <mat-form-field>

      <mat-label>Enter Session Period</mat-label>

      <mat-date-range-input [rangePicker]="picker">
        <input matStartDate placeholder="From Date" required formControlName="fromDate">
        <input matEndDate placeholder="To Date" required formControlName="toDate">
      </mat-date-range-input>

      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <mat-date-range-picker #picker></mat-date-range-picker>

      <!-- Invalid Date Messages -->
      <mat-error *ngIf="dateRangeForm.controls.fromDate.hasError('matStartDateInvalid')">Invalid start date</mat-error>
      <mat-error *ngIf="dateRangeForm.controls.toDate.hasError('matEndDateInvalid')">Invalid end date</mat-error>

      <!-- Required Date Messages -->
      <mat-error *ngIf="dateRangeForm.controls.fromDate.errors?.required">From Date Required</mat-error>
      <mat-error *ngIf="dateRangeForm.controls.toDate.errors?.required">To Date Required</mat-error>

    </mat-form-field>

    <p>Selected Date Range: {{dateRangeForm.value | json}}</p>

    <button>Submit</button>

</form>

 

In the component.ts file, we’ll import the FormControl, FormBuilder, FormGroup and Validators classes to handle form validations.

the complete class component will look like this:

// app.component.ts
import { Component } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'angular-mat-datepicker-range';

  dateRangeForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
  ) { }


  range = new FormGroup({
    fromDate: new FormControl('', Validators.required),
    toDate: new FormControl('', Validators.required)
  });

  ngOnInit(): void {
    this.dateRangeForm = this.formBuilder.group({
      fromDate: new FormControl('', Validators.required),
      toDate: new FormControl('', Validators.required)
    });
  }

  onFormSubmit() {
    console.log('Is Form Invalid', this.dateRangeForm.invalid);
  }
}

 

After adding the template and class component code the application will render a form having Datepicker with range selection and validation applied using the Reactive form approach.

Conclusion

Finally, we’re done with Material Datepicker having Range selection with propper Reactive form-based Validation messages. This can be easily plugged into any working form using Reactive form-based validation. The form-group instance can be used to control form status and check error on form-controls.4

Hope this tutorial was helpful, do share comments below.

Stay safe!

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *