In this post, we will go through a complete example of how to build a custom dialog by using the Angular Material Dialog component.
This covers many of the most common-used cases that of the Angular Material Dialog, such as: common dialog configuration options, dialog layout options, passing data into the dialog, and receiving data back.
With a step-by-step tutorial like this one, you should code along as we are going to start with a simple scenario. Features will be progressively added one by one along the way and detailed explanation will be provided as well.
Step 1 of 5 – Declaring a Material Dialog body component
Before we use the Angular Material Dialog, we must import MatDialogModule first:
Notice CourseDialogComponent, it will be the body of custom dialog.
In order for the component to be usable as a dialog body, we can declare it as an entryComponent, otherwise, it will appear the following error while opening the dialog:
Step 2 of 5 – Angular Material Dialog: Creating and opening
With this in place, we are now ready to create our dialog. First, we can open a dialog from one of our components:
Ok let’s see what is going on here:
- In order to create Material Dialog instances, we are injecting the MatDialogservice via the constructor
- Then we are creating an instance of MatDialogConfig, which will configure the dialog with a set of default behaviors
- We are overriding a couple of those default behaviors. For example, we are setting disableClose to true, which means that the user will not be able to close the dialog just by clicking outside of it
- We are also setting autoFocus to true, meaning that the focus will be set automatically on the first form field of the dialog
Angular Material Dialog Configuration Options
The class MatDialogConfig allows us to define a lot of configuration options. Besides the two that we have overridden, here are some other commonly used Material Dialog options:
- hasBackdrop: defines if the dialog should have a shadow backdrop, that will blocks the user from clicking on the rest of the UI while the dialog is opened (default is true)
- panelClass: adds a list of custom CSS classes to the Dialog panel
- backdropClass: adds a list of custom CSS classes to the dialog backdrop
- position: defines a starting absolute position for the dialog. For example, this would show the dialog in top left corner of the page, instead of in the center:
- direction: this defines if the elements inside the dialog are right or left justified. The default is left-to-right (ltr), but we can also specify right-to-left (rtl).
- closeOnNavigation: this property defines if the dialog should automatically close itself when we navigate to another route in our single page application, which defaults to true.
An example of when we would like to set this to false is the Draft Email Dialog of an Email application like Gmail, where the email draft remains opened as we search for ancient emails.
- The MatDialogConfig also provides the properties width, height, minWidth, minHeight, maxWidth, and maxHeight
Step 3 of 5 – Building the Material Dialog body
Let’s now have a look at CourseDialogComponent. This is just a regular Angular component, as it does not have to inherit from any particular class or implement a dialog-specific interface.
The content of this component could also be anything, and there is no need to use any of the auxiliary Angular Material directives. We could build the body of the dialog out of plain HTML and CSS if needed.
But if we want the dialog to have the typical Material Design look and feel, we can build the template using the following directives:
Here are the 3 main directives that we used to build this dialog:
- mat-dialog-title: This identifies the title of the dialog, in this case, the “Angular For Beginners” title on top
- mat-dialog-content: this container will contain the body of this dialog, in this case, a reactive form
- mat-dialog-actions: this container will contain the action buttons at the bottom of the dialog
Step 4 of 5 – Passing Input Data to the Material Dialog
Dialogs are often used to edit existing data. We can pass data to the dialog component by using the data property of the dialog configuration object.
Going back to our AppComponent, here is how we can pass some input data to the dialog:
We can then get a reference to this data object in CourseDialogComponent by using the MAT_DIALOG_DATA injectable:
As we can see, the whole data object initially passed as part of the dialog configuration object can now be directly injected into the constructor.
We have also injected something else, a reference to the dialog instance named dialogRef. We will use it to close the dialog and pass output data back to the parent component.
Step 5 of 5 – Closing The Dialog + Passing Output Data
Now that we have an editable form inside a dialog, we need a way to pass the modified (or new) data back to the parent component.
We can do via the close() method. We can call it without any arguments if we simply want to close the dialog:
But we can also pass the modified form data back to AppComponent in the following way:
In the component that created the dialog, we can now receive the dialog data in the following way:
As we can see, the call to dialog.open() returns a dialog reference, which is the same object injected in the constructor of CourseDialogComponent.
We can then use the dialog reference to subscribe to the afterClosed()observable, which will emit a value containing the output data passed to dialogRef.close().