Reputation: 1150
I am using mat-checkbox
of Angular Material
and I have added a change
event as below...
<div *ngFor="let subscriber of selectedSubscribers">
<mat-checkbox (change)="onSubscriberCheck(subscriber)">
{{ subscriber.name }}
</mat-checkbox>
</div>
The onSubscriberCheck(subscriber)
code is as below...
onSubscriberCheck(subscriber: Subscribers) {
if (subscriber.checked) {
//Do Something
} else {
//Do Something else
}
}
Here on click of the checkbox, I am always getting the value of subscriber.checked
as undefined
.
My expected result is, if it is checked, then the value should be true
instead of undefined
. If it is unchecked, then the value should be false
instead of undefined
.
EDIT
If I add [(ngModel)]
, then the checkbox list does not work properly. Let me add the complete scenario...
I have 2 sets of checkbox lists. One is a set of checked
checkbox list and below that one I will be showing a set of unchecked
checkbox list. So, in onSubscriberCheck(subscriber)
event, the Do Something
is as below..
onSubscriberCheck(subscriber: Subscribers) {
if (subscriber.checked) {
this.selectedSubscribers.push(subscriber);
this.unselectedSubscribers = this.unselectedSubscribers.filter(s => s.id !== subscriber.id);
} else {
this.unselectedSubscribers.push(subscriber);
this.selectedSubscribers = this.selectedSubscribers.filter(s => s.id !== subscriber.id);
}
}
So, here both [(ngModel)] = subscriber.checked
and change
event fires. How to overcome this one?
I just want to show the checked checkboxes at the top of the list and unchecked checkboxes at the bottom. So, on change event, I am rearranging the arrays selectedSubscribers
and unselectedSubscribers
SECOND EDIT
I am using the below functions to populate the Subscribers
GetSelectedSubscribers() {
this.selectedSubscribers = this.allSubscribers
.filter(subscriber => subscriber.id !== undefined)
.map(subscriber => ({ id: subscriber.id, name: subscriber.name, checked: subscriber.checked }));
}
GetUnselectedSubscribers(){
this.unselectedSubscriberGroupItems = this.subtractListIds(this.allSubscriberGroupItems, this.selectedSubscriberGroupItems);
this.unselectedSubscribers = this.unselectedSubscriberGroupItems.lists.map(subscriber => ({ id: subscriber.id, name: subscriber.name, checked: subscriber.checked }));
}
Here the last checkbox name is coming as empty but has checkbox control. Don't know why it is not displaying..
Please clarify...
Upvotes: 1
Views: 2699
Reputation: 58039
The argument of the method change
of the mat-checkBox is a MatCheckboxChange
, see the API. Futhermore, you get this argument using $event
You can choose use the two binding [(ngModel)] or use the event (change) and the property [checked].
As Naren explain using ngModel, I want to show another approach. The idea is use an unique array and sort the array.
<div *ngFor="let subscribe of subscribers;let index=index">
<mat-checkbox [checked]="subscribe.checked"
(change)="subscribe.checked=$event.checked;sort()">
{{ subscribe.name }}
</mat-checkbox>
</div>
where
subscribers: any = [
{ checked: false, name: 'test'},
{ checked: false, name: 'test2'},
...
]
And the function sort
sort()
{
setTimeout(()=>{
this.subscribers.sort((a:any,b:any)=>
(a.checked && b.checked) ||(!a.checked && !b.checked)?
a.name>b.name?1:-1:
a.checked?-1:
1)
})
}
It's necessary the setTimeout, else the mat-checkbox mark the position where we are.
Upvotes: 1
Reputation: 58334
You need to bind the checked
variable to an ngModel
please find below working example!
html
SELECTED
<div *ngFor="let subscriber of selectedSubscribers">
<mat-checkbox
[(ngModel)]="subscriber.checked"
(ngModelChange)="onSubscriberCheck()"
>
{{ subscriber.name }}
</mat-checkbox>
</div>
<br /><br />
UNSELECTED
<div *ngFor="let subscriber of unselectedSubscribers; trackBy: trackByFn">
<mat-checkbox
[(ngModel)]="subscriber.checked"
(ngModelChange)="onSubscriberCheck()"
>
{{ subscriber.name }}
</mat-checkbox>
</div>
ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatRadioModule } from '@angular/material/radio';
import { FormsModule } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatCardModule } from '@angular/material/card';
/**
* @title Configurable checkbox
*/
@Component({
selector: 'checkbox-configurable-example',
templateUrl: 'checkbox-configurable-example.html',
styleUrls: ['checkbox-configurable-example.css'],
standalone: true,
imports: [
MatCardModule,
MatCheckboxModule,
FormsModule,
MatRadioModule,
CommonModule,
],
})
export class CheckboxConfigurableExample {
allSubscribers: any = [
{
checked: false,
name: 'test',
},
{
checked: false,
name: 'test2',
},
];
unselectedSubscribers: any = [];
selectedSubscribers: any = [];
ngOnInit() {
this.unselectedSubscribers = this.allSubscribers;
}
onSubscriberCheck() {
this.selectedSubscribers = this.allSubscribers.filter(
(x: any) => x.checked
);
this.unselectedSubscribers = this.allSubscribers.filter(
(x: any) => !x.checked
);
}
trackByFn(i: number, val: any) {
return val.name;
}
}
Upvotes: 1