Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Close Angular Material Dialog On Browser Back

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??

like image 334
Brian Bauman Avatar asked Dec 08 '17 23:12

Brian Bauman


People also ask

How do you close a material dialogue?

By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header.

How do I stop angular modal dialog closing?

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 do I stop MatDialog from closing when I click outside?

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.


2 Answers

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();
  }

}
like image 61
Murhaf Sousli Avatar answered Sep 22 '22 18:09

Murhaf Sousli


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;
        }
    }
}
like image 40
Valeriy Katkov Avatar answered Sep 26 '22 18:09

Valeriy Katkov