Prevent Closing Angular Material Dialog by Clicking Outside (Angular 4+)
- Angular Material provides a built-in
MatDialog
component for creating modal dialogs. - These dialogs typically have a dark backdrop behind them, making the dialog the main focus on the screen.
- By default, users can close the dialog by:
- Pressing the Escape (Esc) key.
- Clicking the close icon in the dialog header (if present).
- Clicking anywhere outside the dialog itself (on the backdrop).
Disabling Click Outside to Close:
There are two main approaches to achieve this:
-
Configuration During Dialog Opening:
- When opening the dialog using the
MatDialog.open()
method, you can pass a configuration object with thedisableClose
property set totrue
. This disables both Esc key and backdrop click closing:
import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; export class MyComponent { constructor(private dialog: MatDialog) {} openDialog() { const config: MatDialogConfig = { disableClose: true }; this.dialog.open(MyDialogComponent, config); } }
- When opening the dialog using the
-
Handling Backdrop Click in Dialog Component:
- Inject the
MatDialogRef
service into your dialog component. - Set the
disableClose
property ofMatDialogRef
totrue
to prevent the default closing behavior. - Subscribe to the
backdropClick()
observable ofMatDialogRef
. This observable emits an event when the backdrop is clicked. - Inside the subscription, manually close the dialog using the
close()
method ofMatDialogRef
. This allows you to potentially perform custom actions before closing.
import { MatDialogRef } from '@angular/material/dialog'; export class MyDialogComponent { constructor(private dialogRef: MatDialogRef<MyDialogComponent>) { this.dialogRef.disableClose = true; this.dialogRef.backdropClick().subscribe(() => { // Optional: Perform actions before closing this.dialogRef.close(); }); } }
- Inject the
Choosing the Right Approach:
- If you simply want to prevent closing by both Esc key and backdrop click, the first approach (configuration) is more concise.
- If you need to execute custom logic before closing the dialog in response to a backdrop click, the second approach is more suitable.
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
export class MyComponent {
constructor(private dialog: MatDialog) {}
openDialog() {
const config: MatDialogConfig = {
disableClose: true // This disables both Esc key and backdrop click closing
};
this.dialog.open(MyDialogComponent, config);
}
}
In this example, the disableClose
property is set to true
within the MatDialogConfig
object passed to the dialog.open()
method. This configuration applies globally to the opened dialog, preventing closing by both the Esc key and clicking outside.
import { MatDialogRef } from '@angular/material/dialog';
export class MyDialogComponent {
constructor(private dialogRef: MatDialogRef<MyDialogComponent>) {
this.dialogRef.disableClose = true; // Prevent default closing behavior
this.dialogRef.backdropClick().subscribe(() => {
console.log('Backdrop clicked!'); // Optional: Perform custom actions before closing
this.dialogRef.close(); // Manually close the dialog
});
}
}
Here, the disableClose
property is set to true
on the MatDialogRef
instance within the dialog component's constructor. This prevents the default closing behavior.
Next, the backdropClick()
observable of MatDialogRef
is subscribed to. This observable emits an event whenever the backdrop is clicked. Inside the subscription, you can optionally perform custom actions (like logging a message in this example) before manually closing the dialog using dialogRef.close()
.
- Use Example 1 if you simply want to prevent closing by both Esc key and backdrop click.
- Use Example 2 if you need to execute custom actions before closing the dialog in response to a backdrop click.
-
Global Configuration (Advanced):
While not directly an alternate method, you can potentially set a global default for
disableClose
using Angular providers. This approach requires caution as it can affect all dialogs in your application. Here's an example (use with discretion):import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog'; @NgModule({ providers: [ { provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { disableClose: true } } ] }) export class AppModule { }
In this case, all dialogs opened using
MatDialog.open()
would havedisableClose
set totrue
by default, unless explicitly overridden during dialog opening with a configuration object.
Important Considerations:
- Accessibility: Disabling closing by clicking outside can hinder accessibility for users who might rely on it. Ensure you provide a clear way for users to close the dialog through other means, such as a close button or keyboard shortcuts.
- User Experience: Consider if preventing outside click closing aligns with the expected user experience. In some cases, users might find it frustrating if they can't close the dialog by clicking the background.
- Customizable Closing Behavior: While these methods prevent closing by clicking outside, you might still want to allow closing through other interactions (like buttons or specific key presses). You can achieve this by handling those events within your dialog component and calling
dialogRef.close()
accordingly.
angular dialog modal-dialog