Reputation: 547
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...
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>
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',
});
}
Upvotes: 1
Views: 1487
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;
}
}
Upvotes: 1