Rijo
Rijo

Reputation: 3043

Angular material date picker how to show the title

I need to show the title or importance of the day when user hover particular day. When user mouse over the calendar popup eg: December 25th i need to show a message "Happy Christmas".

I tried following HTML but its not working

<mat-form-field>
      <input matInput [matDatepicker]="picker" (click)="picker.open()" placeholder="Choose a date">
      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <mat-datepicker #picker [dateClass]="dateClass" title="ariaLabel"></mat-datepicker>
    </mat-form-field>

ts file

ariaLabel = (d: Date) => {
    const date = d.getDate();
    return (date === 25) ? 'Happy Christmas' : undefined;
  }

How to implement custom message on particular day in Angular material?

Upvotes: 2

Views: 3813

Answers (1)

Eliseo
Eliseo

Reputation: 57939

Thanks to this question in stackoverflow we can join all

Really I don't like use querySelectorAll, but I think that is the only way, so go

We has an array of selected dates in the way

  dates = [
    { date: "2019-12-01", text: "one text" },
    { date: "2019-12-20", text: "another text" }
  ];

So, first we are going to use dateClass to give a special color

  dateClass = (d: Date) => {
    const dateSearch = this.dateToString(d);
    return this.dates.find(f => f.date == dateSearch)
      ? "example-custom-date-class"
      : undefined;
  };

I use a auxiliar function to convert date object to string

  dateToString(date: any) {
    return (
      date.getFullYear() +
      "-" +
      ("0" + (date.getMonth() + 1)).slice(-2) +
      "-" +
      ("0" + date.getDate()).slice(-2)
    );
  }

If our class is like

.example-custom-date-class {
  background: orange;
  border-radius: 100%;
}
.example-custom-date-class:hover::after {
  counter-increment: section; 
  content:attr(aria-label);
  position: absolute;
  left: 0;
  top: 24px;
  min-width: 200px;
  border: 1px #aaaaaa solid;
  border-radius: 10px;
  background-color: #ffffcc;
  padding: 12px;
  color: #000000;
  font-size: 14px;
  z-index: 1;
}

We has a "tooltip" that use the value of aria-label. So, we are going to change the arial label. We has a function

  displayMonth() {
    let elements = document.querySelectorAll(".endDate");
    let x = elements[0].querySelectorAll(".mat-calendar-body-cell");
    x.forEach(y => {
      const dateSearch = this.dateToString(
        new Date(y.getAttribute("aria-label"))
      );
      const data = this.dates.find(f => f.date == dateSearch);
      if (data) y.setAttribute("aria-label", data.text);
    });
  }

That we need call when the calendar is opened and when the buttons of navigation are clicked, so we need use some like

  streamOpened(event) {
    setTimeout(() => {
      let buttons = document.querySelectorAll("mat-calendar .mat-icon-button");

      buttons.forEach(btn =>
        this.renderer.listen(btn, "click", () => {
          setTimeout(() => {
            //debugger
            this.displayMonth();
          });
        })
      );
      this.displayMonth();
    });
  }

The html

<mat-form-field class="example-full-width" >
  <input matInput [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker (opened)="streamOpened($event)" [dateClass]="dateClass" #picker panelClass="endDate" ></mat-datepicker>
</mat-form-field>

And the stackblitz

Upvotes: 3

Related Questions