Reputation: 1020
I have an array of users and in HTML I used *ngFor to generate a checkbox for each element. I also have an @Input assignedAccountIds[] which represents the default selected users.
The checkbox element is the following one:
<mat-checkbox
color="primary"
[disabled]="disableCurrentAccountCheckbox && account.id === currentAccountId"
[checked]="isAccountSelected(account)"
(change)="onSelectAccount($event, account)"
>
isAccountSelected method verify if a user exists in the selected items array to know if I need to check it or not, and here is the implementation:
isAccountSelected(account: ClientAccount): boolean {
return (this.assignedAccountIds || []).includes(account.id);
}
On the change output, the method implementation is the following one:
onSelectAccount(event: MatCheckboxChange, account: ClientAccount): void {
if (
!event.checked &&
this.currentAccountId &&
account.id === this.currentAccountId
) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
data: {
message: `You will not be able to see this inspection if you unassign yourself!`,
buttonColor: 'primary',
buttonLabel: 'Unassign',
},
position: {
right: '10px',
bottom: '10px',
},
maxWidth: '580px',
});
dialogRef
.afterClosed()
.pipe(untilDestroyed(this))
.subscribe(result => console.log(result));
} else {
this.selectionChange.emit({ id: account.id, checked: event.checked });
}
}
So, what I'm actually trying to do is to display a confirmation modal when you want to unselect yourself from the list. And only after you select Yes or No from the modal, the checkbox will remain checked or will be unchecked.
Upvotes: 0
Views: 3115
Reputation: 316
As of v15, the best way I've found to do this is to provide a 'noop' MAT_CHECKBOX_DEFAULT_OPTIONS to override the default click behavior:
@Component({
selector: 'app-checkbox-component',
templateUrl: './app-checkbox.component.html',
styleUrls: ['./app-checkbox.component.scss'],
providers: [
{ provide: MAT_CHECKBOX_DEFAULT_OPTIONS, useValue: { clickAction: 'noop' } as MatCheckboxDefaultOptions },
],
})
export class InlineHardCopyDeliveredEventComponent {
isCheckboxChecked = false;
constructor(private dialog: MatDialog) {}
openModal(): void {
this.dialog
.open()
.afterClosed()
.subscribe((result) => {
this.isCheckboxChecked = result;
});
}
}
<mat-checkbox
(click)="openModal()"
[checked]="isCheckboxChecked"
></mat-checkbox>
Upvotes: 0
Reputation: 17958
MatCheckbox
does not provide a built-in way to "intercept" a check/uncheck action. You can only listen to the change event after it happens. However, you can use an ordinary click event to do the intercepting:
Checkbox
<mat-checkbox #cb (click)="confirmAssign($event)">Assigned</mat-checkbox>
Dialog actions
<mat-dialog-actions>
<button mat-button [mat-dialog-close]="false">Cancel</button>
<button mat-button [mat-dialog-close]="true">Unassign</button>
</mat-dialog-actions>
TS
@ViewChild('cb', {static: true}) cb: MatCheckbox;
constructor(public dialog: MatDialog) {}
confirmAssign(event) {
// only intercept if currently checked
if (this.cb.checked) {
// stop the click from unchecking the checkbox
event.preventDefault();
// ask for confirmation
this.dialog.open(ConfirmationDialogComponent).afterClosed().subscribe(confirmed => {
if (confirmed) {
// uncheck the checkbox
setTimeout(() => this.cb.checked = false);
}
});
}
}
Upvotes: 3