I am using Angular Material (5.0.0) to create a Single Page Web Application for mobile devices. I have a scenario when I need to display a dialog. I would like to allow the user to hit back to close the dialog, as it's a very common behavior on mobile (especially on Android).
When this happens currently, the page goes to the previous page. I instead need the button to simply dismiss the dialog.
Any ideas on how this might be accomplished??
By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header.
You can prevent closing of modal dialog by setting the beforeClose event argument cancel value to true. In the following sample, the dialog is closed when you enter the username value with minimum 4 characters. Otherwise, it will not be closed.
How To Prevent MatDialog From Closing When Clicked Outside. By default, you could close a material dialog box by clicking outside dialog box element or by pressing the esape key. Angular Material comes with a built-in property called disableClose the prevents this behavior.
This option is already available
let dialogRef = dialog.open(DialogExample, {
height: '400px',
width: '600px',
closeOnNavigation: true
});
Other ways using routes changes events:
1. From app component
constructor(router: Router, matDialog: MatDialog) {
// Close any opened dialog when route changes
router.events.pipe(
filter((event: RouterEvent) => event instanceof NavigationStart),
tap(() => this.matDialog.closeAll())
).subscribe();
}
2. From dialog component
@Component({
selector: 'example-dialog',
templateUrl: 'example-dialog.html',
})
export class ExampleDialog {
constructor(
public dialogRef: MatDialogRef<ExampleDialog>,
router: Router
) {
// Close dialog ref on route changes
router.events.pipe(
filter((event: RouterEvent) => event instanceof NavigationStart),
tap(() => this.dialogRef.close()),
take(1),
).subscribe();
}
}
As a workaround you can add CanActivateChild guard to the root route. The guard will cancel navigation if an dialog is open and close the dialog.
The routes configuration:
const rootRoutes: Routes = [{
path: '',
canActivateChild: [ CanActivateChildGuard ],
children: [
...
]
}];
And the guard:
export class CanActivateChildGuard implements CanActivateChild {
constructor(
private readonly router: Router,
private readonly location: Location
) {}
canActivateChild(route: ActivatedRouteSnapshot): boolean {
if (this.dialog.openDialogs.length > 0) {
// fix navigation history, see github issue for more details
// https://github.com/angular/angular/issues/13586
const currentUrlTree = this.router.createUrlTree([], route);
const currentUrl = currentUrlTree.toString();
this.location.go(currentUrl);
this.dialog.closeAll();
return false;
} else {
return true;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With