Suzed
Suzed

Reputation: 487

Setting disabled to angular material components using directive

As the title says I am trying to set disabled to material component using a directive. I've tried various ways, using ElementRef, Renderer, Renderer2 and querySelector. Nothing seems to be working.

Here it my code. Any help is appreciated.

import { Directive, Input, TemplateRef, ViewContainerRef, Renderer2, ElementRef } from '@angular/core';
import { PermissionType } from './permission-type.enum';
import { Resource } from './resource.enum';
import { PermissionManagerService } from './permission-manager.service';

@Directive({
  selector: '[appIsGranted]'
})
export class IsGrantedDirective {

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private permissionManagerS: PermissionManagerService,
    private _renderer: Renderer2,
    private el: ElementRef
  ) { }

  @Input() set appIsGranted(permission: Array<string>) {
    this.isGranted(
      permission[0] as Resource,
      permission[1] as PermissionType
    )
  }

  private isGranted(resource: Resource, permissionType: PermissionType) {
    if(this.permissionManagerS.isGranted(resource, permissionType)) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      let view = this.viewContainer.createEmbeddedView(this.templateRef);
      let rootElem = view.rootNodes[0];
      //this.el.nativeElement.disabled = true;
      //this.el.nativeElement.disabled = 'disabled';
      //this._renderer.setProperty(rootElem, 'disabled', true);

      this._renderer.setProperty(rootElem, 'disabled', 'disabled');

//      this.viewContainer.clear();
    }
  }

}

For example this button icon is what I am trying to disable.

<button mat-icon-button class="action--icon" matTooltip="Notes" matTooltipPosition="above" (click)="openNotesDialog(element.earningsFileId)" *appIsGranted="['EARNINGS', 'viewearnings']">
  <mat-icon>chat</mat-icon>
</button>

The idea would be that this would work across all material items by just adding the attribute disabled to all material components.

Upvotes: 1

Views: 1073

Answers (1)

DaggeJ
DaggeJ

Reputation: 2201

We are doing something similar in our app through a directive that gets passed a list of roles required for running the actions associated with the element it is set on.

It works by using JQuery's method attr to set disabled and other attributes.

The directive;

@Directive({
    selector: '[appEditEntityActions]'
})
export class EditEntityActionsDirective implements OnInit {
    @Input() requiresAnyRole: string[] = null;

    constructor(
        private authorizationService: AuthorizationService,
        private element: ElementRef) { }

    ngOnInit() {
        var userCanEdit = this.authorizationService.hasAnyClaim(this.requiresAnyRole);
        if (!userCanEdit) {
            this.turnOffElement();
        }
    }

    private turnOffElement(): void {
        var jqElem = $(this.element.nativeElement);

        jqElem.off();
        jqElem.find('*').off();

        // app-opac-50-disabled-cursor-not-authorized is a css class that sets cursor, transparency etc...
        jqElem
            .attr('disabled', 'disabled')
            .attr('href', '')
            .addClass('app-opac-50-disabled-cursor-not-authorized')
            .attr('title', 'Not authorized');

        jqElem
            .find('button')
            .addClass('text-muted')
            .attr('disabled', 'disabled');

        jqElem.find('a')
            .attr('href', '')
            .addClass('app-opac-50-disabled-cursor-not-authorized');

        jqElem.on('click', (e: Event) => {
            e.preventDefault();
        });
    }
}

Usage;

<button appEditEntityActions [requiresAnyRole]='["Viewer", "Editor"]' (click)="doSomething();">Sample button</button>

Hope it helps you.

Upvotes: 1

Related Questions