14

I am using mat-calendar. I am trying to highlight certain dates but I couldn't do it. There is no proper documentation for this.

HTML

<mat-card>
  <mat-calendar name="appointment_date" [selected]="selectedDate (selectedChange)="onSelect($event)"></mat-calendar>
</mat-card>

TS

onSelect(event){
  this.selectedDate= event;
}

What I need:

Image

halfer
  • 19,824
  • 17
  • 99
  • 186
Felix Christo
  • 301
  • 1
  • 3
  • 19

5 Answers5

19

You can use the the input binding dateClass as describe in the Angular Material documentation here. Note: This requires an Angular Material version of at least 7.1.0

Change your template to this:

<mat-calendar [dateClass]="dateClass()" [selected]="selectedDate" (selectedChange)="onSelect($event)"></mat-calendar>

And in your component add the dateClass function which will generate a function that will return a type of MatCalendarCellCssClasses, which can be as simple as a string representing the CSS class to apply (or an array of class names):

dateClass() {
  return (date: Date): MatCalendarCellCssClasses => {
    if (date.getDate() === 1) {
      return 'special-date';
    } else {
      return;
    }
  };
}

And finally in your styles.css add the classes you want applied:

.special-date {
  background-color: red;
}

Here is a stackblitz that colors the first of each month in red.

Fabian Küng
  • 5,925
  • 28
  • 40
  • I have array of dates, is it is possible to highlight those dates? – Felix Christo Jan 30 '19 at 11:53
  • 1
    Sure, you could extend the function to check if the date is one that is in your array and then return the required CSS class. The function will be evaluated for each date that is currently show on your calendar. – Fabian Küng Jan 30 '19 at 11:54
  • `["2019-01-22T18:30:00.000Z", "2019-01-22T18:30:00.000Z", "2019-01-24T18:30:00.000Z", "2019-01-28T18:30:00.000Z", "2019-01-24T18:30:00.000Z", "2019-01-23T18:30:00.000Z", "2019-01-22T18:30:00.000Z", "2019-01-25T18:30:00.000Z"]` I am getting those values from backend. Can you now explain clearly please – Felix Christo Jan 30 '19 at 11:58
  • I couldn't import `MatCalendarCellCssClasses` throwing error – Felix Christo Jan 30 '19 at 12:05
  • 1
    I have updated the stackblitz to check against the array of dates. From here you should be able to adjust/troubleshoot yourself.If not, update your question with what you have tried to resolve it. – Fabian Küng Jan 30 '19 at 12:08
  • your stackblitz is very clear brother thank you but I couldn't import `import { MatCalendarCellCssClasses } from '@angular/material';` throwing error – Felix Christo Jan 30 '19 at 12:13
  • 1
    Just saying `throwing error` doesn't really help. What does the error say? Which Angular Material version are you using? `MatCalendarCellCssClasses` is only available from version 7+ as far as I know. – Fabian Küng Jan 30 '19 at 12:19
  • Error: `Module '"../../../../../node_modules/@angular/material/material"' has no exported member 'MatCalendarCellCssClasses'. [2305]` I am using Material 7.0.1 – Felix Christo Jan 30 '19 at 12:38
  • 1
    You need at least version 7.1.0 of Angular Material. See the [changelog](https://github.com/angular/material2/blob/master/CHANGELOG.md#710-stone-silhouette-2018-11-20), it was added in 7.1.0 – Fabian Küng Jan 30 '19 at 12:50
11

Complementing Fabian's answer, if you have problem seeing the highlighted color and you are using lazy loading components, remember to add the ::ng-deep in front of the class. Like this:

::ng-deep.special-date {
   background-color: red;
}

Cheers!

Alejandro Barone
  • 1,743
  • 2
  • 13
  • 24
1

if datas are loaded through service then you have to use *ngIf="datas" on the mat-calendar, so that dateClass will called after the data comes in. ie:

html:

<div *ngIf="datas">
  <mat-calendar [dateClass]="dateClass()" ></mat-calendar>
 </div>

ts:

dateClass() {
  return (date: Date): MatCalendarCellCssClasses => {
    const highlightDate = this.datas.map(strDate => new Date(strDate))
      .some(d => d.getDate() === date.getDate() && d.getMonth() === date.getMonth() && d.getFullYear() === date.getFullYear());
    return highlightDate ? 'special-date' : '';
  };
}


ngOnInit() {
  this.studentreportsService.getHeatMap(this.studentid)
  .subscribe(data => {
    this.datas = data; // ["2019-01-22", "2019-01-24"]
  });
}
suhailvs
  • 20,182
  • 14
  • 100
  • 98
1

If the style is still not applied, try make the style important:

::ng-deep.highlight-date {
    background: red !important;
}
Martin Staufcik
  • 8,295
  • 4
  • 44
  • 63
0

@Fabian Küng's answer on stakblitz was giving me an error stating that date.getDate() was not a function.

I solved it by assigning date to a new Date(). My code looks like this:

return (date: Date): MatCalendarCellCssClasses => {
      date = new Date(date); // <<< My edit
      const highlightDate = this.datesToHighlight
        .map(strDate => new Date(strDate))
        .some(d => {
          return d.getDate() === date.getDate() && d.getMonth() === date.getMonth() && d.getFullYear() === date.getFullYear()
        });

      return highlightDate ? 'special-date' : '';
    };
sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40