Build a Custom Calendar with Angular Material Calendar

Maria Zacharia
3 min readOct 26, 2020

--

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.

Get/Set the selected date:

  • 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.

Set minimum and maximum date:

  • 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>

Handle date-change event:

  • 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>

Handle month-change event:

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>

Handle year-change event:

  • 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>

Highlight specific dates:

  • 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>

Apply custom date filter:

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

--

--

Maria Zacharia

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