Build a Custom Calendar with Angular Material Calendar

I was recently working on building a feature similar to calendly by myself. In order to implement that, I wanted a base calendar component and I decided to go with the mat-calendar component provided by Angular. Surprisingly, I couldn’t find much good documentation about the same. So like every other developer, I had to go through several stack overflow links and other materials to get my task done.

In this article, you will find all the customizations which I tried out on the component. For most of the obvious use cases, I have directly listed the steps to implement without much explanation.

  • Declare a variable of type Date in the ts file.
selectedDate: Date = new Date();
  • Map it to the selected parameter of the mat-calendar component as shown below:
<mat-calendar [(selected)]="selectedDate"></mat-calendar>

The above two steps would launch the mat-calendar with the present date selected. If the user chooses another date later, you will be able to access it via the same variable.

  • Define two variables minDate and maxDate in the ts file and assign appropriate values.
minDate = new Date(2020, 0, 1);
maxDate = new Date(2050, 11, 31);
  • Map the above two values to the minDate and maxDate parameters of the mat-calendar component.
<mat-calendar [minDate]="minDate" [maxDate]="maxDate"></mat-calendar>
  • Define the following function in the ts file.
dateChanged(event) {
console.log("Date changed", event);
//handler logic
}
  • Map the handler function to the selectedChange event on the mat-calendar component.
<mat-calendar (selectedChange)="dateChanged($event)"></mat-calendar>

The calendar month change can happen in two ways:

Using next-month and previous-month buttons on the calendar header

To handle this, add the below piece of code to ngAfterInit lifecycle method:

By going to the year select UI

To handle this,

  • Define the following function in the ts file.
handleMonthSelected(event) {
console.log("Month changed", event);
//handler logic
}
  • Map the handler function to the monthSelected event on the mat-calendar component.
<mat-calendar (monthSelected)="handleMonthSelected($event)"></mat-calendar>
  • Define the handler function to be invoked when the year change happens:
handleYearSelected(event) {
console.log("Year changed", event);
//handler logic
}
  • Map the handler function to the yearSelected event on the mat-calendar component.
<mat-calendar (yearSelected)="handleYearSelected($event)"></mat-calendar>
  • Define a custom class in the CSS file depending on the styling you need to apply on the highlighted date
.special-date {
background-color: green;
border-radius: 100%;
}
  • Define a variable, say datesToBeHighlighted, in the ts file which contains the list of dates to be highlighted.
  • Add the function given below to the ts file. The function checks if the given date is part of the list of dates to be highlighted. If yes, it returns the custom class we defined in step one, else it returns an empty string.
  • Finally, map the function to the dateClass parameter on the mat-calendar component.
<mat-calendar [dateClass]="dateClass()"></mat-calendar>

The use case here is to make certain dates non-selectable within the calendar. Let’s say, we need to make all the Saturdays and Sundays disabled on the calendar. To do that, follow the steps below:

  • Define the following function in the ts file:
disableWeekendsFilter = (d: Date): boolean => {
return (d.getDay() !== 0 && d.getDay() !== 6);
}
  • Map the above function to the dateFilter parameter on the mat-calendar component
<mat-calendar [dateFilter] = "disableWeekendsFilter"></mat-calendar>

Well, we can still do a lot more with this component. For instance, it is possible to get a completely customized look for the calendar header. But I am yet to try that out.

If you like what you read and would like to hire me for a one-on-one session, reach out to me using

https://hiretheauthor.com/maria

Co-Founder & CTO at Hire the Author. Want to have a 1–1 with me? Reach out to me at https://hiretheauthor.com/maria