Search code examples
htmlangulartypescriptprimeng

Is it possible to use [maxSelectedLabels] property in an ngif condition?


I'm using Prime NG Multiselect component and I want to show selectedItemsLabel="{0} Selected" when there are more than 3 selected checkboxes, but if all of the checkboxes are selected, then selectedItemsLabel="All" should be shown in the placeholder.

I'm new to angular and I been following documentation of this MultiSelect component, yet this doesn't show the options to able to implement multiple conditions of properties, and I was wondering if it's even possible.

Example of how It might be

 <ng-template pTemplate="filter" let-value let-filter="filterCallback">
                            <p-multiSelect
                                [ngModel]="value"
                                [options]="routeOptions"
                                placeholder="Any"
                                (onChange)="filter($event.value)"
                                optionLabel="name"
                                selectedItemsLabel="{0} selected"
                                [maxSelectedLabels]="3"
                            >
                                <ng-template let-option pTemplate="item">
                                    <div>
                                        <span class="p-ml-1">{{ option.name }}</span>
                                    </div>
                                    <div *ngIf="[maxSelectedLabels="routeOptions.length - 1"] Then selectedItemsLabel="All"></div>
                                </ng-template>
                            </p-multiSelect>
                        </ng-template>

Solution

  • Yes, you can. First give the component a ref with # like this:

    <p-multiSelect
      #myMultiSelect
      [ngModel]="value"
      [options]="routeOptions"
      placeholder="Any"
      (onChange)="filter($event.value)"
      optionLabel="name"
      selectedItemsLabel="{0} selected"
      [maxSelectedLabels]="3"
      >
    .......
    

    Then you have access to it:

    <div *ngIf="myMultiSelect.maxSelectedLabels === routeOptions.length - 1">Im visible</div>
    

    If the option of maxSelectedLables is the length - 1 of routeOptions then the div is visible. That is how ngIf works

    BUT

    Thats not what you want. You wanna set the selectedItemsLabel property. And you have it not understand correctly. You set the maxSelectedLables to 3 as example AND set the selectedItemsLabel directly, too! The text of the selectedItemsLabel will be only shown if needed (controlled by the component).

    <h5>Basic</h5>
    <p-multiSelect #meins [options]="cities" [(ngModel)]="selectedCities" defaultLabel="Select a City" optionLabel="name"
      [maxSelectedLabels]="3" selectedItemsLabel="{0} items selected">
    </p-multiSelect>
    

    Look here the Stackblitz!

    The documentation of ng-prime will helps, too and say:

    selectedItemsLabel: Label to display after exceeding max selected labels e.g. ({0} items selected), defaults "ellipsis" keyword to indicate a text-overflow.

    UPDATE 18.02.2023

    You wanna show "ALL" only if all items selected. So add the onChange event and bind the selectedItemsLabel. Why binding? It has some problems with a condition in it. So we make it inside the code.

    HTML

    <p-multiSelect [options]="cities" [(ngModel)]="selectedCities" defaultLabel="Select a City" optionLabel="name"
      [maxSelectedLabels]="2" [selectedItemsLabel]="bindTest" (onChange)="onChange()">
    </p-multiSelect>
    

    Inside the code do the follow with onChange:

    Code

      onChange() {
        if (this.selectedCities.length === this.cities.length) {
          this.bindTest = "ALL";
          this.changeRef.detectChanges();
        }
         else {
           this.bindTest = "{0} items selected";   
           this.changeRef.detectChanges();
        }
      }
    

    Now it works how you wish. One important thing: We use changeRef.detectChanges(); Without this the components selected text will not changing directly. Import it in the components constructor:

      constructor(
        private countryService: CountryService,
        private primengConfig: PrimeNGConfig,
        private changeRef: ChangeDetectorRef
      ) {
    .....