One of the most commonly used form components that we need for building Applications with Angular is some form of datepicker.
If you are building an Angular application, there is no need to use third-party components that are not Angular-based, such as for example the jQuery datepicker.
Instead, as part of the Angular Material library you have a powerful datepicker written in Angular and ready to be used, that is responsive and that has been battle-tested and used in thousands of applications.
I'm talking about the Angular Material datepicker, that is jam-packed with tons of useful options that you might not be aware of.
In this post, we are going to guide you through this datepicker component in detail, covering everything from the simplest to the most advanced features.
Table Of Contents
In this post, we will cover the following topics:
- Setting up the Angular Material Datepicker
- Adding a modal calendar to the datepicker
- Opening the calendar dialog when clicking on the input
- Configuring the mat-datepicker-toggle icon
- Preventing the user from manually typing in dates
- Configuring the starting view mode of the calendar
- Configuring the starting date of the calendar
- Limiting the input range of a datepicker
- Custom validation of dates with matDatepickerFilter
- Configuring the look and feel of the calendar
- Adding custom styles to certain dates in the calendar
- Support for mobile devices
- Using the calendar in standalone mode
- Summary
This post is part of our ongoing series on Angular Material, you can find all the articles available here.
So without further ado, let's get started learning everything that we need to know about the Angular Material Datepicker!
Setting up the Angular Material Datepicker
Here is an example of a typical datepicker:
As we can see, this datepicker is composed of 3 separate elements:
- an input text field, used to type in the date manually
- a calendar modal dialog, that shows up next to the input field and allows the user to choose a date visually
- a calendar icon, that you can use to open or close the calendar dialog
Let's then create a datepicker by adding these 3 elements progressively, and explain how everything is connected together.
Let's start with the plain input field:
As we can see, this is just a plain Angular Material input field, with no date input capabilities yet.
The field is linked to a form control via the Angular Forms formControlName
directive, and the name of the date field is releasedAt
.
The field has an outline appearance, so that we can see that nice border around the input, and notice the use of the matInput
directive.
Without this directive applied properly to the HTML input, the input component will not work correctly.
Adding a modal calendar to the datepicker
To this plain input, we are now going to add a modal calendar element next to it:
Notice the use of the [matDatepicker]
directive, that links the input field with the modal element.
If you try this out now, you won't see anything different at this stage, because the modal calendar is hidden by default.
To be able to open it or close it, we need a toggle button. We are going to add it to the end of the input field as a suffix, and connect it with the modal calendar:
Notice the use of the [for]
directive, that links the toggle button to the datepicker.
And with this, we have now finished the minimal set up of our datepicker, and we can now open the calendar and use it to choose a date, it's that simple!
But this is just the basic usage of the datepicker component. In the rest of this post, we are going to cover a ton of commonly used features and configuration options that you have available for the datepicker.
Opening the calendar dialog when clicking on the input
First, let's start with a very common feature that you might be asked to implement, which is to automatically open the calendar once the corresponding input gets clicked.
You can do just by adding a normal event click handler, and calling the calendar.open()
method:
Configuring the mat-datepicker-toggle icon
Sometimes you might want to configure the look and feel of the toogle calendar button.
Notice that the calendar toggle shows up to the right of the input field, and this is due to the use of the matSuffix
directive.
The matSuffix
is a configuration directive for the material input field, that will ensure that the calendar icon is added at the end (to the right) of the input field.
If instead you want to show the calendar icon to the left of the input field, you can do so by using matPrefix
instead of matSuffix
.
Here is what your datepicker will look like:
Besides configuring the positioning of the icon, you can also configure the icon itself.
By default, the mat-datepicker-toggle
will show up as a calendar icon, but you can choose to use any other icon of the Material design icon library.
For example, there are tons of other calendar-related icons that you might prefer instead: Material design calendar icons.
Here is how you can use an alternative calendar icon:
Notice the use of the matDatepickerToggleIcon
directive, without it this would not work.
And here is what your calendar will look like with the new icon:
Preventing the user from manually typing in dates
Normally you want to allow the user to be able to input dates in the two different ways: manually via the input field and visually via the calendar.
But if you want, you can disable the input field, and that will prevent the user from typing in some date.
The problem is, both the toggle button and the calendar will inherit the disabled state, so the user won't be able to enter any date at all.
But you can override this, and allow the user to still enter a date visually using the modal calendar:
As you can see, you need to override the disabled property on both the toggle button and the calendar in order for this to work.
Configuring the starting view mode of the calendar
By default, the calendar dialog opens with a monthly view of the month associated with the date value.
If no value is set, today's date will be shown as highlighted in the current month.
For a lot of dates this is the intended behaviour, but for other dates it would be better to start with a yearly view.
For example, if it's a birthday date, starting with today's date does not make a lot of sense. Instead, we would prefer to first select a decade, then a year, then a month, etc.
We can configure the view mode of the calendar by using the startView
property:
And here is what the calendar yearly view will look like:
And if instead of year
, we use multi-year
, this is what the calendar will look like:
Configuring the starting date of the calendar
It's also possible to set the starting date of the calendar to a different value than the value of the form control.
We need to start by defining a member variable in our controller with the start date:
startDate = new Date(2010, 0, 1)
Then all we have to do is to pass the start date to the date picker:
Limiting the input range of a datepicker
Sometimes we want to restrict what dates the user can enter using the calendar.
If we want to define an acceptable range of dates, we need to define a couple of member variables in our component:
minDate = new Date(2010, 0, 3);
maxDate = new Date(2010, 0, 15);
Then we need to pass these limits using the [min]
and [max]
directives to the matInput
directive:
And this what the datepicker will look like:
As we can see, the dates outside of the valid range are disabled, so the user can't click on them.
Custom validation of dates with matDatepickerFilter
Sometimes we need a bit more control about which dates are valid or not.
For example, imagine that we have a situation where the user should only be able to pick Mondays from the calendar.
To implement this, the first thing that we need is a date filter function:
This function returns true if the date is a Monday, and false otherwise. Now all we have to do is to plug it into the datepicker:
And this is what the calendar will look like, as we can see only Mondays are enabled:
Configuring the look and feel of the calendar
By default, the datepicker will use the primary palette of our Angular Material theme to highlight the selected date.
But it's also possible to use one of the alternative palettes, such as the accent palette or the danger pallete.
This is how we configure the calendar to use the accent palette:
And this is how the calendar will look like:
If instead we want to use the danger palette, we can use warn
instead of
accent
as the color property.
Adding custom styles to certain dates in the calendar
Sometimes we need a bit more control over the styling of each date cell.
Imagine an air flight booking website, where we would like to highlight the period between the start and end of the flight with a different background color.
Or to take a simpler example, let's say that we want to highlight every 1st day of the month with a different color in the month view only.
The first thing that we need to do is to create a date class function:
This function returns the highlight-date
CSS class only for the first day of each month, and no CSS classes otherwise.
Now, all we have to do is to plug it into the datepicker like this:
And this is what the datepicker will look like, in the monthy view:
Support for mobile devices
The default behavior of the datepicker is ideal for desktop devices, and it works on mobile too, but the dates in the modal dialog might be too close to each other for the user to comfortably select them.
But if you anticipate that your application is going to be used mostly on mobile, and you want to make inputting dates easier for the user, you can activate a larger, touch-friendly interface for the datepicker.
You can do so by setting the touchUi
property to true:
This property will make the modal dialog much bigger and more mobile-friendly:
Using the calendar in standalone mode
Sometimes, you just want to show to the user a calendar with an associated input field, so that the user can choose a date directly inline in the page without typing it in manually.
You can do so in the following way, by using the mat-calendar
component:
And this is what your inline calendar will look like:
Summary
I hope that you have enjoyed this post. If you would like to learn a lot more about Angular Material, we recommend checking the Angular Material In Depth course, where all sorts of Angular Material components and best practices are covered in great detail:
Also, if you have some questions or comments please let me know in the comments below and I will get back to you.
To get notified of upcoming posts on Angular Material and other Angular topics, I invite you to subscribe to my newsletter:
And if you are just getting started learning Angular, have a look at the Angular for Beginners Course: