El viaje del Usuario

Todos tenemos usuarios, clientes o beneficiarios en nuestros emprendimientos, proyectos o procesos. (Es obvio, pero bueno, no se me ocurría como introducir el tema, sigamos). Para diferenciarnos del…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




How to create a Modal Dialog component in Angular 8

Modal dialogs are great for when you need to restrict a user to a particular action before they can return to the normal use of the application. For instance, when you try to close Microsoft Word without saving, it shows a dialog where you choose to resume your work (the “Cancel” option) or close the program (by either saving or not saving your work). The modal dialog appears because you can’t continue using Word as long as you don’t choose one of the options available. Until then, you can only stare at the dialog.

But let’s look at another example: a logout operation. Say, the user clicks the logout button in your application but, instead of logging them out right away, you want to confirm that’s what the user is trying to do. After all, they might have clicked the button by mistake. Incidentally, that is what I will be showing you today, how to create a logout modal dialog component in Angular (8). Once the user clicks the logout button, a modal pops up with only two options for the user: “Logout”, which confirms the user’s intention, and “Go back”, which closes the modal and returns the user to the normal use of the application.

Before we get into the code, I want to preface it by clarifying that this article is written under the assumption that you are already familiar with Angular. The resulting application itself is very simple so if you have a basic understanding of the framework you should be fine. To use the modal we will only need two things: to create a button in the root component (app-root) and create a new component, which will be the modal itself.

First up, we need to create a new Angular project through the command line:

The first command creates a new project called modal-component. When prompted for routing, you can choose whatever you prefer as it doesn’t affect this example. For the stylesheet format, choose CSS. The second command moves us inside the folder created for the project. The third command, code ., is a handy shortcut to open Visual Studio Code in the current working directory, that is, the project’s folder. This is just a nice shortcut if you’re using Visual Studio Code as your editor.

Now that we have our project open in the code editor, there’s one thing we need to install in the project: Angular Material. If you’re not familiar, it includes a bunch of pre-made components ready to be added to a project. In this example, we’ll be making use of its MatButton for, you guessed it, the buttons and MatDialog to create the modal dialog.

So, to install the library, return to the command line and enter

ng add @angular/material

Now that Angular Material is set, we just need to do one last thing that’s not actual code: create the modal component. I mean, not the finished version of course, but the component which will be the modal. For that, enter

ng generate component modal

in the command line. And so this command creates a new component in the application called modal (or rather, app-modal). Now we can finally start writing code!

The first thing we’ll do is add a new key the @NgModule in theapp.module.ts file, as well as some imports, as shown in the following code gist:

According to the documentation, this is the purpose of entryComponents: “The set of components to compile when this NgModule is defined, so that they can be dynamically loaded into the view”. In practice, if this was not set, then the MatDialog would not be loaded properly (in our case the MatDialog will make use of ModalComponent, the component we created earlier). For the imports, well, we need to import the Angular Material modules we will be using.

Now that all the setup is out of the we can finally focus on writing HTML, CSS and TypeScript. Oh and by the way, you can run the project by entering

ng serve --open

in the command line. This opens the project in your browser and will rebuild the project whenever you modify it, so you can check it out throughout the article to see how it changes.

Before touching any component, let’s set the global styles right away in the styles.css file:

For now focus only on the changes to the html and body elements, we’ll come back to the mat-dialog-container#modal-component ruleset later.

With the global styles defined, we can move on to the individual components. Let’s start with the app-root component, the “home page” of the application, which will look like this:

app-root component
app-root component

That’s it, just a lonely logout button in the center of the screen. Clicking it will trigger the logout modal component, that is, before actually logging out the user, we first ask them for confirmation. To reiterate, when the modal appears, the user can either confirm the logout or return to the application.

So, let’s start with the HTML:

As you can see, it’s simple. A main element holds the whole component, which contains just one other element: the logout button. But due notice the mat-raised-button attribute. That’s what transforms the normal HTML button into an Angular Material button, including its associated styles and animations. Though, we also give it an idto alter slightly its styles:

Pretty simple as well, with only the text color, background color and borders of the button changed. Nothing else regarding the CSS for app-root. Now there’s one last thing we need to change for this component: its TypeScript. Our objective is to create the function which is called when the logout button is clicked. And what does the function actually do? Open the modal component, that is, a MatDialog:

Ok, now let me explain what happens in this file. First notice that there are three new imports: MatDialog and MatDialogConfig(both from Angular Material) and ModalComponent, the class of the component we have created. In the class constructor of app-root, we inject a dependency: the MatDialog which we have been talking about since the beginning. If we didn’t inject it, then we wouldn’t be able to open a dialog.

Then, we do two things inside the openModal() function: configure the dialog to be opened with a MatDialogConfig object and actually open the modal. We make use of four configuration options:

In the last line of the function, we open the modal dialog by calling the open() method of the MatDialog object injected in the constructor. To open a dialog, we need to specify which will be the component rendered inside along with a corresponding configuration object.

And that’s it for the app-root component, now when you click the logout button it will open an empty modal dialog!

Now we need to look at the app-modal component, the component we created. Again, we’ll need to change its HTML, CSS and TypeScript, but first, let me show you what the modal will look like in the end:

The modal dialog
The modal dialog

Again, we are starting with the HTML:

We have a single div element that wraps all the content of the modal, and then that content is separated in three parts:

Fairly simple stuff as well, and notice how we’ve used MatButtons once again for the modal.

Now, the CSS has a trick behind it because of Angular Material.

What is shown above is fairly straightforward CSS. In the first ruleset (#modal-content-wrapper) we transform the dialog into a three-row grid, one row for each of the parts enumerated. The remaining rulesets are used just for positioning and minor style adjustments (note: if you’re unfamiliar with the CSS grid layout, I have written an introductory article here in case you are interested).

What is tricky about the modal’s CSS is styling theMatDialog Angular Material component. If you look at the stylesheet above, there’s no ruleset for the design of the dialog itself. modal-content-wrapper is the id of the HTML element that wraps all of the content inside the modal, not the actual modal.

Enter the MatDialog configuration object. Remember when we wrote the configurations for the dialog to be opened in app-root? We passed it a custom id, modal-component, which we can now use to style the dialog. But we can’t do that in the CSS of app-modal as that is in fact the content of the dialog, not the dialog itself. Hence that ruleset I asked you to ignore back in styles.css. While this file contains the global CSS rulesets, we have no other choice but to set the styles for this particular MatDialog here.

Unlike the buttons that are “transformed” into MatButtons by adding the mat-raised-button attribute, which still allow us to modify the button’s styles in the CSS of the components where they are used, the dialog works differently as it is almost in a limbo between app-root (where it is opened) and app-modal (the component it contains). In short, we style the MatDialog in the global styles.css file because we can’t access it in neither of the other component’s stylesheets.

But, as we are dealing with global styles, we need to be careful with the specificity of our ruleset so it doesn’t affect other dialogs we might have in the application. Thus, let’s look at the styles.css code gist once again.

Look at the last ruleset, that’s the one responsible for the styles of our MatDialog. We use a CSS selector of tag name (mat-dialog-container), which catches any MatDialog in the application, and then restrict it only to those that have an id of modal-component, in other words, we are selecting only the logout modal we are working with. Angular Material components can be tricky to style so there’s a clear trade-off between their usability and the needs of each project.

With the CSS out of the way, there’s just one last thing to change, which is the app-modal‘s TypeScript. Here we need to do three things:

Whichever button the user clicks, for the sake of this demo, they will be returned to the “home page” of the application. In other words, whichever button the user clicks, the modal will close and show the big “Logout” button once more.

So, what’s the difference between the “Logout” button (the one inside the modal), and the “Go back” button? The first displays an alert box before closing the modal to let the user know they have logged out. The second button simply closes the modal.

Now let’s step back from the demo for a minute. Once the user clicks the “Logout” button and the application calls the actionFunction() function, that’s where your logic to execute the desired action comes in. In the case of a real logout, that’s where you’d have the code for wrapping up the user’s session. The other function, the function that cancels the operation the user initiated, simply closes the dialog and lets them return to the normal use of the application.

And with this we also have reached the end of the explanation. If you’ve followed along with the code, you now have a working modal dialog component which was dead simple to implement. Of course, in your real application you’ll be including services to interact with the server, and a modal can be applied wherever you need the user to confirm their action before actually executing it, such as when deleting an item.

If you have the project running, open your browser at localhost:4200 to see its finalized state. If it is not running, type ng serve --open in the command line and it will open a new tab in your browser automatically.

All constructive feedback is welcome as this is the longest technical article I’ve written and there’s probably plenty of ways in which I can improve. Have a great day :)

Add a comment

Related posts:

The Privilege Of Home

I first experienced the intensity of leaving home aged eighteen heading off to spend three months in Senegal — an overwhelming sensation of anxiety, impossible to distinguish from excitement. To…

You matter more than your tool

Practical questions that will help you cut through the clutter and select the best productivity tool for you.

Streamline Roofing Projects with a Ridge Cap Forming Machine

A ridge cap forming machine is a powerful tool that revolutionizes the roofing industry by providing an efficient and precise solution for manufacturing ridge caps. These machines offer a range of…