que1326
que1326

Reputation: 2325

Angular material mat-button doesn't update the disabled change from outer directive

I have a simple custom directive that needs to make the element disabled.

<button mat-button [myCustomDirective]="'mode1'">Edit</button>

@Directive({
  selector: '[myCustomDirective]'
})
export class MyCustomDirective implements OnInit {
  @Input() myCustomDirective: string;

  @Input()
  @HostBinding('disabled')
  public disabled: boolean;

  constructor(
    private el: ElementRef,
    private cd: ChangeDetectorRef
  ) {}

  ngOnInit() {

    switch (this.myCustomDirective) {
      case 'mode1':
        this.disabled = true;
        this.el.nativeElement.disabled = true;

        setTimeout(() => {
          this.cd.markForCheck();
          this.cd.detectChanges();
        });

        break;

      default:
        this.el.nativeElement.remove();

        break;
    }
  }
}

DEMO

Even if the disabled attribute appears in the DOM, the mat-button doesn't get fully update ( the disabled styles are missing, because some of the disabled classes that angular material haves for the mat-button are missing also from the DOM ). So mat-button doesn't updates. Any suggestions for this ?

Upvotes: 0

Views: 1988

Answers (1)

Andrew Allen
Andrew Allen

Reputation: 8042

Your stackblitz and question are different. I've made a best guess at what you're looking for.

The answer here using AfterViewInit works.

You also need to add class mat-button-disabled

import {
  Directive,
  ElementRef,
  Renderer2,
  AfterViewInit,
  Input
} from '@angular/core';

@Directive({
  selector: '[appHasPermissions]'
})
export class HasPermissionsDirective implements AfterViewInit {
  @Input() myCustomDirective: string;

  constructor(private el: ElementRef, private renderer: Renderer2) {
    // try with Renderer2
    this.renderer.setProperty(this.el.nativeElement, 'disabled', true);
  }

  ngAfterViewInit() {
    switch (this.myCustomDirective) {
      case 'mode1':
        // try with ElementRef
        this.el.nativeElement.disabled = true;
        this.renderer.addClass(this.el.nativeElement, 'mat-button-disabled');
        break;
      default:
        this.el.nativeElement.remove();
        break;
    }
  }
}
<button 
  appHasPermissions
  [myCustomDirective]="'mode1'"
  mat-raised-button
  color="warn">
    From directive
</button>

Stackblitz

Upvotes: 1

Related Questions