You need to do the following:
- Remove an unncessary
[(ngModel)] (you have two) and the [compareWith] from <mat-select>:
<mat-select placeholder="State2" multiple [(ngModel)]="modelGroup" #itemSelect="ngModel">...</mat-select>
- Instead of creating an array for each options group with regular expression you can create one single array called
groups which will look like the following:
groups: any[] = [
{
name: 'ETHERNET',
items: [
{
label: "640K",
value: "BS640KB_ETHERNET",
defaultValue: true
},
{
label: "7MB",
value: "BS7MB_ETHERNET",
defaultValue: true
},
{
label: "7MB NOQinQ",
value: "BS7MB_ETHERNET_NOQinQ",
defaultValue: true
},
{
label: "20MB",
value: "BS20MB_ETHERNET",
defaultValue: true
}
]
},
{
name: 'ATM',
items: [
{
label: "640K",
value: "BS640K_ATM",
defaultValue: true
},
{
label: "7MB",
value: "BS7M_ATM",
defaultValue: true
},
{
label: "20MB",
value: "BS20M_ATM",
defaultValue: true
}
]
},
{
name: 'ETH',
items: [
{
label: "2MB",
value: "BS2MB_SHDSL_ETH",
defaultValue: true
},
{
label: "4MB IMA",
value: "BS4MB_SHDSL_ETH_IMA",
defaultValue: true
},
{
label: "6MB IMA",
value: "BS6MB_SHDSL_ETH_IMA",
defaultValue: true
},
{
label: "8MB IMA",
value: "BS8MB_SHDSL_ETH_IMA",
defaultValue: true
}
]
},
{
name: 'SHDSL ATM',
items: [
{
label: "2MB",
value: "BS2MB_SHDSL",
defaultValue: true
},
{
label: "4MB B",
value: "BS4MB_SHDSL_B",
defaultValue: true
},
{
label: "4MB IMA",
value: "BS4MB_SHDSL_IMA",
defaultValue: true
},
{
label: "6MB IMA",
value: "BS6MB_SHDSL_IMA",
defaultValue: true
},
{
label: "8MB IMA",
value: "BS8MB_SHDSL_IMA",
defaultValue: true
}
]
}
];
Furthermore you can remove all other arrays, regular expressions, your createCatArray() and equals() method.
- Now we can clean up the template. Go on and remove all existing
<mat-optgroup>. Add now one single <mat-optgroup> which loops through your set up array groups and renders the corresponding items like the following:
<mat-optgroup *ngFor="let group of groups" [label]="group.name">
<mat-option *ngFor="let item of group.items" [value]="item.value">
{{item.label}}
</mat-option>
</mat-optgroup>
- Remove now the parameter you have set up on the Select All button:
<button mat-button (click)="selectAll(itemSelect)">Seleziona Tutti</button>
- Now the last step is to change the
selectAll() method. Within the method remove the parameter array and the existing for loop. Now we are going to loop through the set up groups array and add the value of each item in every group to a values array. This array will later be submitted to update the selected values. The method should look like the following:
selectAll(select: NgModel) {
let values: any[] = [];
for(let group of this.groups){
for(let item of group.items){
values.push(item.value);
}
}
select.update.emit(values);
}
Basically we did the following:
Created an array of groups which further contains the name of the group and the items which belong to the group.
Loop through the array of groups to render the groups and their corresponding items in the html template.
Added a select all method which loops through all groups items and add their value to an array which will be submitted later to update the selection.
Here is the functioning app:
https://stackblitz.com/edit/angular5-selectall-with-groups-knptuu