Update
Although we are able to get checked/unchecked, but it's really annoying to implement subscription for every mat-select
.
So here is solution, I created a Directive
which has a event checkboxChanged
and it is invoked when mat-option
is checked/unchecked
To implement this in your project
1.Simply copy and paste the file mat-select-checkbox-changes.directive.ts
from here into you project and import accordingly and start using like below.
<mat-select multiple appMatSelectCheckboxChanges [(ngModel)]="selectedFood" [compareWith]="compareWith" (checkboxChanged)="checkboxChanged($event)">
<mat-option *ngFor="let food of foods" [value]="food.value">{{food.viewValue}}</mat-option>
</mat-select>
checkboxChanged(evt: { value: Food, isChecked: boolean }) {
console.log(`${evt.value} is ${evt.isChecked ? 'checked' : 'unchecked'}`);
}
Adding directive code here below(incase links broken)
import { Directive, EventEmitter, Output, OnDestroy } from "@angular/core";
import { MatSelect } from "@angular/material/select";
import { Subscription } from "rxjs";
interface IMatSelectCheckboxChanges {
value: any;
isChecked: boolean;
}
@Directive({
selector: "[appMatSelectCheckboxChanges]"
})
export class MatSelectCheckboxChangesDirective implements OnDestroy {
@Output() checkboxChanged = new EventEmitter<IMatSelectCheckboxChanges>();
subscription: Subscription;
constructor(private matSelect: MatSelect) {
this.subscription = this.matSelect.optionSelectionChanges.subscribe(matOption => {
if (matOption.isUserInput) {
this.checkboxChanged.next({ value: matOption.source.value, isChecked: matOption.source.selected });
}
}
);
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
Original
Use optionSelectionChanges
observable.
1.Get mat-select
reference
@ViewChild(MatSelect) matSelect: MatSelect;
@ViewChild('#favFood') favFoodselect: MatSelect;
@ViewChild('#favAnimal') favAnimalselect: MatSelect;
2.Subscribe to the changes
this.subscription = this.matSelect.optionSelectionChanges.subscribe(matOption => {
if (matOption.isUserInput) {
console.log(`${matOption.source.viewValue} is ${matOption.source.selected ? 'checked' : 'unchecked'}`);
}
});
Some Details
The above subscription will also called, if you initially assign any value(default value)
So to prevent that, add if
check using matOption.isUserInput
Don't forget to unsubscribe observable
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
Stackblitz Demo