prime-ng Dropdown - disable certain SelectItems

北城以北 提交于 2019-11-30 23:28:51

here is my workaround:

1) extend original SelectItem's interface (reference) with disabled property, so merged interface will look like

interface SelectItem {
  label: string;
  value: any;
  disabled: boolean;
}

this may be done by declaring new interface with the same name:

interface SelectItem {
  disabled: boolean;
}

2) based on p-dropdown component's template, modify this part of template:

<li *ngFor="let option of optionsToDisplay;let i=index" 
    [ngClass]="{'ui-dropdown-item ui-corner-all':true, 'ui-state-highlight':(selectedOption == option), 
                        'ui-dropdown-item-empty':!option.label||option.label.length === 0}"
    (click)="onItemClick($event, option)">
  <span *ngIf="!itemTemplate">{{option.label||'empty'}}</span>
  <ng-template [pTemplateWrapper]="itemTemplate" 
               [item]="option" 
               *ngIf="itemTemplate"></ng-template>
</li>

by adding disabled: option.disabled to li's ngClass directive, so when option is set to disabled, 'disabled' CSS class will be added to the il element. Also, onItemClick($event, option) should not be triggered by clicking on disabled options, and itemClick flag should be set to true, which will prevent dropdown closing. This can be achieved by rewriting the click function to

(click)="!option.disabled && onItemClick($event, option) || itemClick = true"

dropdown closing is done by onMouseclick($event) function, which has following condition:

if (!this.itemClick) {
  ...
}

so, setting itemClick flag true for disabled options will prevent dropdown closing when clicking on disabled items.

This may be done by using metadata reflection API. Import Dropdown class and get its metadata:

import { DropdownModule, Dropdown, SelectItem } from 'primeng/primeng';

...

// modify dropdown component's template
Reflect.getMetadata('annotations', Dropdown).forEach(annotation => {
  if (annotation.constructor.name === 'DecoratorFactory') {
    // add 'disabled' CSS class for disabled options
    annotation.template = annotation.template.replace("'ui-dropdown-item ui-corner-all':true, ", "'ui-dropdown-item ui-corner-all':true, disabled: option.disabled, ");
    // do not trigger click function on disabled options and set itemClick flag to prevent dropdown closing
    annotation.template = annotation.template.replace('(click)="onItemClick($event, option)"', '(click)="!option.disabled && onItemClick($event, option) || itemClick = true"');
  }
}); 

3) add desired CSS for disabled items, for example:

.ui-dropdown-item.ui-corner-all.disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

That is it :) Tested on primeng@4.1.2

plunker: https://plnkr.co/edit/0Pqq565BPowABUauW7Y7

You can also disable any item in primeng dropdown using ng-template, click event and custom style as below:

    cars: any[];
    selectedCar: string;
  1. Initialize the cars array of object that is essential an extension of Interface SelectItem with added property disabled: boolean

    ngOnInit(): void {
     this.cars = [];
     this.cars.push({label: 'Audi', value: 'Audi'});
     this.cars.push({label: 'BMW', value: 'BMW'});
     this.cars.push({label: 'Fiat', value: 'Fiat', disabled: true});
     this.cars.push({label: 'Ford', value: 'Ford'});
     this.cars.push({label: 'Honda', value: 'Honda', disabled: true});
     this.cars.push({label: 'Jaguar', value: 'Jaguar'});
     this.cars.push({label: 'Mercedes', value: 'Mercedes'});
     this.cars.push({label: 'Renault', value: 'Renault'});
     this.cars.push({label: 'VW', value: 'VW'});
     this.cars.push({label: 'Volvo', value: 'Volvo'});
    }
    
  2. Method that gets triggered on click event

    onClick(disabled: boolean) {
            if(disabled) {
                event.stopPropagation();
            }
        }
    
  3. Customizing the Primeng Dropdown using ng-template and adding ng-style

    <p-dropdown [options]="cars" [(ngModel)]="selectedCar" [style]="{'width':'150px'}">
            <ng-template let-option pTemplate="item">
                <div>
                    <div (click)="onClick(option.disabled)" [ngStyle]="option.disabled? {'color': '#ccc', 'cursor': 'default'} : ''"> {{option.label}} </div>
                </div>
            </ng-template>
        </p-dropdown>
    

Credit: ogousa (primeng forum)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!