Search code examples
angulartypescriptangular-directiveng-zorro-antd

How to access the nested element of a ElementRef.nativeElement in angular


I am using NG-ZORRO library and would like to customize it's DatePicker.
For example, I would like to highlight some of the days with different color like screenshot below, and the days that I would like to highlight are dynamic (based on a date list get from database):
enter image description here

My idea was create a directive, bind the host element with ElementRef and add custom class to the element with Renderer2. Here is what I have so far:

html

<nz-date-picker nzInline customDatePicker></nz-date-picker>

ts

@Directive({
    selector: `[customDatePicker]`
})
export class CustomDatePickerDirective {

    constructor(@Host() @Self() @Optional() public hostDatePicker: NzDatePickerComponent, renderer: Renderer2, hostElement: ElementRef) {
        console.log(this.hostDatePicker);
        renderer.addClass(hostElement.nativeElement, 'custom-color');
    }
}

The problem is renderer.addClass will only add the custom class at top element (<nz-date-picker> element), but the element I need to inject the custom class is within this element, I am thinking if there is any way I can look for the child/nested elements? I inspect the <nz-date-picker> element with devtools, the element that I will need to add the custom class is pretty deep inside (within the red box of the screenshot below): enter image description here


Solution

  • You can use vanilla JS for this. You can use the title attribute to easily pick a cell:

    @Directive({
      selector: `[customDatePicker]`,
    })
    export class CustomDatePickerDirective {
      @Input() highlights: {day: string, color: string}[] = [];
      constructor(private hostElement: ElementRef) {};
    
      ngAfterViewInit() {
        const datePicker = this.hostElement.nativeElement as HTMLElement;
        for (const h of this.highlights) {
          const cell = datePicker.querySelector<HTMLElement>(`[title='${h.day}']`);
          cell.style.backgroundColor = h.color;
        }
      }
    }
    
    <nz-date-picker nzInline customDatePicker [highlights]="highlights"></nz-date-picker>
    
    export class AppComponent {
      highlights = [
        { day: '7/8/2022', color: 'red' },
        { day: '7/18/2022', color: 'green' },
      ];
    }
    

    Of course you can set classes instead of just colors. The syntax is cell.classList.add('className').

    stackblitz: https://stackblitz.com/edit/angular-ivy-wap1jw?file=src/app/custom.directive.ts