Angular 2 material datepicker highlight special da

2020-03-06 07:25发布

问题:

I've been looking around for a way to mark up special days in the calendar to the user. I know that you can disable certain days in the datepicker but I would like to be able to just mark/style certain days, for instance change background/color to red on dates that have a special value, holidays for instance, and not disable them.

I have not found any way to do this, sorry if I have missed something obvious. Have anyone found a way to do this or is it easier to just make my own datepicker in this case?

回答1:

If you look at the HTML of an open datepicker, you will see each day is represented by a td, like so:

<td class="mat-calendar-body-cell ng-star-inserted" role="gridcell" tabindex="-1" aria-label="February 4, 2018" style="width: 14.2857%; padding-top: 7.14286%; padding-bottom: 7.14286%;"><div class="mat-calendar-body-cell-content">4</div></td>

What we can derive from that HTML is an aria-label and a class of mat-calendar-body-cell.

To achieve what you want, you can use the @Output() openedStream event. This will be triggered whenever the calendar is opened.

As per the docs: @Output('opened') openedStream: EventEmitter<void>.

Once you receive the event, you can then query the DOM by the mat-calendar-body-cell class that has a combination of an aria-label attribute with a certain date, and if there are matches then you can add a class to those matches.

Let me know if you have any issues with that. But you should be able to follow that rubric step by step to achieve what you want.

For more options from the datepicker API, look at the docs here.



回答2:

html:

<mat-calendar [minDate]="minDate" [maxDate]="maxDate" [selected]="selectedDates" (selectedChange)="selectedChange($event)" [headerComponent]="displayMonth()" [startAt]="startDate"></mat-calendar>

.ts:

    import { Component, OnInit, Input, OnChanges, ViewEncapsulation, ElementRef, Renderer2 } from '@angular/core';

constructor(
    private elRef: ElementRef,
    private renderer: Renderer2
) {}

        displayMonth() {
            let HeaderElsClass = this.elRef.nativeElement.getElementsByClassName('mat-calendar-body-cell');
            let orderDate = this.convertDate.dateFormat(this.tempOrdersDate, 'MMMM D, YYYY'); 
            // tempOrderDate is epoch array, i convert from epoch to date

            for(let index in HeaderElsClass) {
              if(typeof HeaderElsClass[index] === 'object') {
                let headerClass = HeaderElsClass[index].getAttribute('aria-label');

                orderDate.find(each => {
                  if(each === headerClass) {
                    this.renderer.addClass(HeaderElsClass[index], 'mat-calendar-body-active');
                    this.renderer.setStyle(HeaderElsClass[index], 'font-weight', '900');
                  }
                  return false;
                })
              }
            }
          }

this working fine in my code. i hope work to you.

thanks, Abdullah



回答3:

mat-datepicker has a dateClass input that does exactly this. Pass it a function that accepts a Date and return a class name to apply.

Example from docs:

<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 [dateClass]="dateClass" #picker></mat-datepicker>
</mat-form-field>

dateClass = (d: Date) => {
  const date = d.getDate();

  // Highlight the 1st and 20th day of each month.
  return (date === 1 || date === 20) ? 'example-custom-date-class' : undefined;
}

.example-custom-date-class {
  background: orange;
  border-radius: 100%;
}

Note in my case I had to apply the background to .mat-calendar-body-cell-content, a direct child of .example-custom-date-class, rather than to the class directly as in the example.