Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to limit Angular Material multiple select items to N items?

In using https://material.angular.io/components/select/overview#multiple-selection

How to limit the number of items selected to N number? Where N is 3 or 4 or 5.

like image 987
Jek Avatar asked Jul 03 '18 06:07

Jek


3 Answers

The best solution is based on only if you disable only unselected options. Otherwise it is meaningless because after you disable all options, then how is that possible to unselect any of options?

in HTML component:

<mat-form-field>
  <mat-select placeholder="Category" [formControl]="categories" multiple>
    <mat-option *ngFor="let cat of categoryArr" [value]="cat.id"
      [disabled]="isOptionDisabled(cat.id)">
      {{cat.title}}
    </mat-option>
  </mat-select>
</mat-form-field>

in controller:

isOptionDisabled(opt: any): boolean {
  return this.categories.value.length >= 3 && !this.categories.value.find(el => el == opt)
}

Now: Only already selected options are enable to do something, other options are disabled, as follows:

Only already selected options are enable to do something, other options are disabled

User can uncheck any of checked options so that user have chance to be able to do check/uncheck on the form field.

like image 96
LuDeveloper Avatar answered Oct 14 '22 17:10

LuDeveloper


Set the selectionChange output event on the mat-select component, point it to your component function: (selectionChange)="changed()".

snippet:

<mat-select placeholder="Toppings" [formControl]="toppings" (selectionChange)="changed()" multiple>

In your component create a global variable named mySelections. This will store your selections :) It will hold an array of strings.

It looks like this:

mySelections: string[];

changed() {
  if (this.toppings.value.length < 3) {
    this.mySelections = this.toppings.value;
  } else {
    this.toppings.setValue(this.mySelections);
  }
}

Change the number 3 to N and presto, you're done.

like image 34
Carsten Avatar answered Oct 14 '22 18:10

Carsten


You can do this using the disabled property on the mat-option like so:

<mat-select formControlName="myCtrl" multiple>
            <mat-option [disabled]="formGroup.get('myCtrl').value?.length > 2 && !formGroup.get('myCtrl').value?.includes(o)"
                        *ngFor="let o of itemList"
                        [value]="o">{{o.name}}
            </mat-option>
</mat-select>
like image 40
Rob Avatar answered Oct 14 '22 19:10

Rob