I need to mark the days that have any task in the mat calendar, but i can´t find why is not working this code.
here goes the ts
dateClass(): any {
return (date: Date): MatCalendarCellCssClasses => {
const findDate = this.tasks.find((task) =>
moment(task.date_required.toDate()).isSame(moment(date), 'day')
);
if (findDate !== undefined) {
console.log(findDate)
return 'date-with-task';
} else {
return;
}
};
}
these are the component imports
import {
ChangeDetectorRef,
Component,
EventEmitter,
HostListener,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewEncapsulation,
} from '@angular/core';
the variable tasks is an input from a parent component
@Input() tasks: any[];
and here is the html where i use the mat calendar
<div class="calendar-container" [ngStyle]="{'display': !showingCalendar ? 'none' : ''}">
<mat-calendar class="calendar-tasks" [dateClass]="dateClass()" [(selected)]="selectedDay"
(selectedChange)='selectedChange($event)' (monthSelected)='monthSelected($event)' [startAt]='currentMonth'>
</mat-calendar>
<div class="border-bottom"></div>
</div>
also, i made this class in scss so i could see if the code it´s working
.date-with-task{
border-color: red;
}
i read all the forums i could find and i also watched some yt videos about mat calendas, but i couldn´t find the answer. If someone could help me i'll be really grateful :)
i needed to find the days with tasks marked in red, but nothing happened
A few changes are required for your code to work as intended:
Use an arrow function
You're currently using a regular function. Inside it, this
is the function's scope, not the class instance.
For access to the class instance via this
, you have to use an arrow function 1:
export class MyComponent {
@Input() tasks: any[];
dateClass = (date: Date): MatCalendarCellCssClasses => {
console.log(this.tasks) // inside your function was `undefined`
if (someCondition) {
return 'some-class'
}
return ''
}
}
<button />
button.mat-calendar-body-cell
. If you style those buttons, two adjacent dates will touch each other. I suggest you style the inner cell content (.mat-calendar-body-cell-content
):.test-class .mat-calendar-body-cell-content {
border-color: red;
}
border: none
, which means you need to set more than border-color
for the border to become visible (border: 1px solid red;
would work); additionally, you might want to add some border-radius
(they're boxy by default).<mat-calendar>
. To remove the CSS scoping, use ViewEncapsulation.None
(or add your styles to an un-scoped stylesheet):@Component({
encapsulation: ViewEncapsulation.None
})
Working example 2, 3.
1 - The function should be modified to return a string according to your business logic.
2 - The more verbose version of dateClass
in the example would be:
dateClass = (date: Date): MatCalendarCellCssClasses => {
if (
this.tasks
.map((t) => t.date_required)
.find((d) => moment(d).isSame(date, 'day'))
) {
return 'test-class'
}
return ''
}
3 - Alternatively, you could type dateClass
as MatCalendarCellClassFunction<Date>
:
dateClass: MatCalendarCellClassFunction<Date> = (date) =>
(this.tasks
.map((t) => t.date_required)
.find((d) => moment(d).isSame(date, 'day')) &&
'test-class') ||
'';