1

I'm looking to build an angular-material datepicker (Angular Material 11), but I have a small feature that's needed and I just can't seem to crack.

It needs to look like in the picture below:

Target datepicker

The problem I have is with the extra text that appears in each of the day cells. I've tried the [dateClass] attribute but to no avail:

template:

<mat-datepicker [dateClass]="dateClassArrow"></mat-datepicker>

.ts component:

constructor(availableItemsService...) {}

dateClassArrow = date => {
  const noItems: string = this.availableItemsService.getAvailableItems(date);
  document.documentElement.style.setProperty('--availableItems', noItems);
  return 'class-that-contains-content';
}

.scss


:root {
  --availableItems: 1;
}

.class-that-contains-content {
  ...
}

.class-that-contains-content:before {
  content: --availableItems;
}

Also tried without the :before, like

.class-that-contains-content {
  content: attr(--availableMaterials);
}

Any hints or help would be appreciated.

  • it's closer to this https://stackoverflow.com/questions/59458789/angular-material-date-picker-how-to-show-the-title/59461291#59461291 about show tooltip – Eliseo May 20 '21 at 21:38

1 Answers1

2

I read these blogs for a lot of my understanding on how to do this.

https://blog.angular.io/taking-advantage-of-the-angular-material-datepicker-237e80fa14b3,

https://mariazacharia-k.medium.com/build-a-custom-calendar-with-angular-material-calendar-ebb6806308e5

The second one has a good implementation for adding color changes to the background of specific dates.

I ended up doing this:

here is my .ts file:

import { Component, AfterViewInit, ViewChild, Renderer2 } from '@angular/core';
import { MatCalendar } from '@angular/material/datepicker';
import { Moment } from 'moment';

@Component({
  selector: 'calendar',
  templateUrl: './calendar.component.html',
  styleUrls: ['./calendar.component.css']
})
export class CalendarComponent implements AfterViewInit {
  @ViewChild('calendar') calendar: MatCalendar<Moment>;
  selectedDate: Moment;

  constructor(private _renderer: Renderer2) {

  }

  ngAfterViewInit() {
    const monthPrevBtn = document.querySelectorAll('.mat-calendar-previous-button');
    const monthNextBtn = document.querySelectorAll('.mat-calendar-next-button');

    if (monthPrevBtn) {
      Array.from(monthPrevBtn).forEach((button) => {
        this._renderer.listen(button, 'click', (event) => {
          this.updateCalendar();
        });
      });
    }

    if (monthNextBtn) {
      Array.from(monthNextBtn).forEach((button) => {
        this._renderer.listen(button, 'click', (event) => {
          this.updateCalendar();
        });
      });
    }

    this.updateCalendar();
  }

  handleMonthSelected(event) {
    this.updateCalendar();
  }

  updateCalendar() {
    setTimeout(() => {
      const cells = Array.from(document.querySelectorAll<HTMLDivElement>('.mat-calendar .mat-calendar-body-cell-content'));

      cells.forEach(c => {
        c.innerText = c.innerText.length == 1 ? '0' + c.innerText : c.innerText;
        c.innerHTML = '<div class="row"><div class="col-12" style="font-size:1.5em;">' + c.innerText + '</div><div class="col-12">' + 1 + '</div></div>';//TODO: check date and data and use number from that.
      });

    });
  }
}

Here is my html:

<div class="calendar-wrapper">
  <mat-calendar (monthSelected)="handleMonthSelected($event)" #calendar [(selected)]="selectedDate">
  </mat-calendar>
</div>

This will handle formatting the calendar even when you change months.

enter image description here

Eric Oudin
  • 259
  • 2
  • 4
  • 13