There's a work-around too that is use the dateClass
@ViewChild('picker',{static:false}) calendar: MatDatepicker<any>;
setClass() {
return (date: any) => {
if (date.getDate() == 1) this.changeMonth(
{month:date.getMonth()+1,
year:date.getFullYear()
});
};
}
changeMonth(date)
{
console.log(date)
}
where you has
<mat-form-field>
<mat-label>Choose a date</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker [dateClass]="setClass()"></mat-datepicker>
</mat-form-field>
See stackblitz
Well, nobody has interest in know when the month change if he has no good reason. The typical reason is call to an API that return an array with "specials" days and show in the calendar.
To change the aspect of this specials days we can think that we can use the own function dateClass but remember that we are looking for the days after the function is executed (*). So we need use Renderer2 to add the class.
If the data we received is some like (see that "day" is a string)
[
{day:'2020-02-06',data:'one'},
{day:'2020-02-16',data:'two'},
{day:'2020-02-22',data:'three'}
]
Our function changeMonth becomes like:
changeMonth(date) {
this.dataService.getData(date.month, date.year).subscribe(res => {
setTimeout(() => {
let elements = document.querySelectorAll(".calendar");
if (elements && elements.length) {
const cells = elements[0].querySelectorAll(".mat-calendar-body-cell");
cells.forEach(x => {
const date = new Date(x.getAttribute("aria-label"));
const dateTxt =
date.getFullYear() +
"-" +
("00" + (date.getMonth() + 1)).slice(-2) +
"-" +
("00" + date.getDate()).slice(-2);
if (res.find(x => x.day == dateTxt))
{
this.renderer.addClass(x, "special");
}
});
}
});
});
}
(*) we can also ask for the "special days" in ngOnInit and, then simple use the dateClass function