FlyFish
FlyFish

Reputation: 547

Dynamically Enable/Disable Mat-Selection-List Mat-List-Option

I have the following mat-selection-list. I need it to enable the options in a cascading fashion. i.e. The Second Selection will not be enabled until the First Selection is selected. The Third Selection will not be enabled until the Second Selection is select, etc...

SelectCriteria

Here is the html code for the list:

 <mat-selection-list id='selectedParameters' [(ngModel)]="selectedCriteria">
    <mat-list-option *ngFor="let item of incomingParameters" [selected]="item.selected" [value]="item.name"
        [disabled]="item.disabled" checkboxPosition="before" (click)="GetChange(item)">
        {{item.name}}
    </mat-list-option>
</mat-selection-list>

Here is how I populate the List:
    if (this.data.criteria.FirstSelection) {
        arr.push({
            name: 'First Selection',
            selected: false,
            disabled: 'false',
        });
    }

    if (this.data.criteria.SecondSelection) {
        arr.push({
            name: 'Second Selection',
            selected: false,
            disabled: 'true',
        });
    }

    if (this.data.criteria.ThirdSelection) {
        arr.push({
            name: 'Third Selection',
            selected: false,
            disabled: 'true',
        });
    }

    if (this.data.criteria.FourthSelection) {
        arr.push({
            name: 'Fourth Selection',
            selected: false,
            disabled: 'true',
        });
    }

    if (this.data.criteria.FifthSelection) {
        arr.push({
            name: 'Fifth Selection',
            selected: false,
            disabled: 'true',
        });
    }

    if (this.data.criteria.Sixth Selection) {
        arr.push({
            name: 'Sixth Selection',
            selected: false,
            disabled: 'true',
        });
    }

How can I cascade the enabling/disabling of the options?

Upvotes: 1

Views: 1487

Answers (1)

Naren Murali
Naren Murali

Reputation: 56054

Nice question, here is my solution, get the length of the selected array and enable those that are less than the value!

html

<h1 class="mat-headline">MatSelectionList</h1>
<h2 class="mat-subheading-1">Input compareWith is not triggered</h2>
<mat-selection-list
  #matSelectionList
  [compareWith]="compareServiceTypes"
  [(ngModel)]="data"
  (ngModelChange)="uncheck($event)"
  multiple
>
  <mat-list-option
    checkboxPosition="before"
    [value]="s.id"
    [selected]="data.includes(s.id)"
    *ngFor="let s of serviceTypes; trackBy: s?.id; let i = index"
    [disabled]="i > getMax()"
  >
    {{ s.label }}
  </mat-list-option>
</mat-selection-list>

{{ data | json }}
<div class="mat-small material-version">
  @angular/material: {{ version.full }}
</div>

ts

import { ViewChild } from '@angular/core';
import { Component } from '@angular/core';
import { MatSelectionList, VERSION } from '@angular/material';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @ViewChild('matSelectionList') matSelectionList: MatSelectionList;
  version: any;
  data: any;
  serviceTypes = [];

  constructor() {
    this.version = VERSION;
    this.data = [];
    setTimeout(() => {
      this.serviceTypes = [
        {
          id: 1,
          label: 'Service type 1',
        },
        {
          id: 2,
          label: 'Service type 2',
        },
        {
          id: 3,
          label: 'Service type 2',
        },
        {
          id: 4,
          label: 'Service type 2',
        },
        {
          id: 5,
          label: 'Service type 2',
        },
      ];
    }, 1000);
  }

  uncheck(value) {
    let found = null;
    this.serviceTypes.forEach((item, index) => {
      if (
        (this.data[index] || this.data[index] === 0) &&
        item.id !== this.data[index] &&
        !(found || found === 0)
      ) {
        found = index;
      }
    });
    if (found || found === 0) {
      this.data.splice(found);
    }
  }

  getMax() {
    return this.data.length;
  }

  compareServiceTypes(st1: any, st2: any) {
    console.log('compareServiceTypes');
    // const result = st1 && st2 ? st1.id === st2.id : st1 === st2;
    return st1 && st2 ? st1.id === st2.id : st1 === st2;
  }
}

stackblitz

Upvotes: 1

Related Questions