Really it's a bit complex control the material angular date picker events. I don't know if there're a better aproach, but you can get it using a custom header component, see this SO
Before, we are going to create a dataService
@Injectable({
providedIn: "root"
})
export class DataService {
arrayOfDays = [
new Date("2019-01-01"),
new Date("2020-08-10"),
new Date("2020-09-20")
];
constructor() {}
displayMonth(year: number, view: string) {
setTimeout(() => {
let elements = document.querySelectorAll(".mat-calendar-content");
let x = elements[0].querySelectorAll(".mat-calendar-body-cell-content");
if (view == "multi-year") {
const years = this.arrayOfDays.map(x => x.getFullYear());
x.forEach((y: any) => {
if (years.indexOf(+y.innerHTML) >= 0) {
{
y.style["border-color"] = "red";
}
}
});
}
if (view=="year"){
const monthsIni = [
"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"
];
const months = this.arrayOfDays
.filter(x => x.getFullYear() == year)
.map(x => monthsIni[x.getMonth()]);
x.forEach((y: any) => {
if (months.indexOf(y.innerHTML) >= 0) {
{
y.style["border-color"] = "red";
}
}
});
}
});
}
}
After inject the dataService in the ExampleHeader and in the component, in the Example header is a fwe complex but it's only write
constructor(_intl: MatDatepickerIntl,
@Inject(forwardRef(() => MatCalendar)) calendar: MatCalendar<any>,
@Optional() _dateAdapter: DateAdapter<any>,
@Optional() @Inject(MAT_DATE_FORMATS) _dateFormats: MatDateFormats,
changeDetectorRef: ChangeDetectorRef
,private dataService:DataService
) {
super(_intl,calendar,_dateAdapter,_dateFormats,changeDetectorRef)
}
When handles user clicks on the period label, user clicks on the previous button and user clicks on the next button to call the service
currentPeriodClicked(): void {
this.calendar.currentView =
this.calendar.currentView == "month" ? "multi-year" : "month";
this.dataService.displayMonth(
this.calendar.activeDate.getFullYear(),
this.calendar.currentView
);
}
customPrev(): void {
this.previousClicked();
this.dataService.displayMonth(
this.calendar.activeDate.getFullYear(),
this.calendar.currentView
);
}
customNext(): void {
this.nextClicked();
this.dataService.displayMonth(
this.calendar.activeDate.getFullYear(),
this.calendar.currentView
);
}
Futhermore we need make it also in yearSelected from the main component
yearSelected(event: any) {
this.dataService.displayMonth(
event.getFullYear(),
this.calendar.currentView
);
}
You can see in the stackblitz
Update if only want to "remark" the months, the thing is more simple, because we need only control the (yearSelected)
event, so we can forget about the custom header.
<mat-datepicker #picker [dateClass]="dateClass"
(yearSelected)="yearSelected($event)"
[calendarHeaderComponent]="exampleHeader">
</mat-datepicker>
months = [0,3] //<--in a variable the months we want remark
yearSelected(event:any)
{
setTimeout(()=>{
let elements = document.querySelectorAll(".mat-calendar-content");
let x = elements[0].querySelectorAll(".mat-calendar-body-cell-content");
x.forEach((y: any,month:number) => {
if (this.months.indexOf(month) >= 0) {
{
y.style["border-color"] = "red";
}
}
});
}
)
}
see stackblitz