Click here to share this article on LinkedIn »

Modern websites have modals to either show some piece of information to the user or to get some from them. If you don’t know what a modal is, here is how one looks:

A login modal box

There are some libraries out there that allow you to use bootstrap modals or some other modal types. However, it is highly unlikely that your web application will be needing all the features provided by third-party-libraries. There’s no need to increase your bundle size for a couple of modal screens that you can easily do yourself.

Building blocks of a modal box

An overlay that directs the user’s attention to the modal and hides the background. This is just a simple div that stretches across the screen with a background colour that has some transparency. ( opacity < 1 )

<div id=”overlay”></div> A modal container. This is a simple div that will carry the modal component itself for the time it is shown on the screen. If the user decides to close the modal, this div container will be empty. Later we will see how to append our component to this div container.

<div id=”modal-container></div> The modal itself. Since this is an Angular post, this will be a separate component with its own html, css and javascript.

Overview of the method we are gonna use

First of all we are gonna create the necessary services required to create a systematic way of showing modals. We are gonna create two services namely:

Dom Service Modal Service

Remember to add the services as providers to the necessary module

The Dom service, as the name suggtests, will be responsible for creating and removing dynamically created components from the #modal-container (mentioned above).

The Modal service will use the Dom service to initialise a modal window or to destroy it.

We are gonna look at both of them in detail soon.

But first lets loot at our app.component.html file

app.component.html

We should focus our attention to the two divs at the end of this file. The first div #modal-container is the container in which our dynamically generated component will live until it is killed by the user.

O nly one component can live in the #modal-container at a time as there can be only one modal window on the screen at a time

The second div is the #overlay div. This is responsible for darkening the content behind the modal window. It also has a click event on it which is responsible for closing the modal. This is optional of course.

Notice that both these divs have the class hidden . This class hides both the divs at the start of the application as we don’t want to show a modal window when the user lands on the page. Of course, if that is what you want then you should not use the hidden class.

Since we are talking about the hidden class already, it’s a good time to look at the css classes we will use for our setup

app.component.css

These css properties can be tweaked around with as per your needs. But it gives you a basic modal window and an overlay.

The next thing we are gonna look at is the component itself, that we are gonna show in the #modal-container div. In this case, I named it the Sample Component. It will just show some text. But you can show any component in the modal so the possibilities are endless.

sample component

Here you can see the javascript, HTML and CSS. The modal is using the ModalService that we will create next to call the destroy() method to close the modal when the user presses the close button.

Lets look at the DomService first as it will be used in the ModalService

dom.service.ts

This service is a big one so lets look at it step by step.

The service takes in three services that Angular provides namely:

Talking about these are not in the scope of this article. However, you can google them to understand them better. If you have some Angular experience it won’t be a problem to understand them. Remember the responsibility of the DomService is to dynamically create components and add/remove them to/from the DOM itself.

This service has two public methods namely:

appendComponentTo() removeComponent()

Lets look at the first method. This method takes in three arguments. The parentId , which in this case will be #modal-container since the parent of the component will be our modal container. The second argument is the child . This is the component itself. The third one is the childConfig . This is an object containing the inputs and outputs that will be passed to the child component. Don’t worry about this part, it will make sense soon. The code is commented so it shouldn’t be a problem to understand it. However, there are a couple of lines I would like to go over.

this.childComponentRef = childComponentRef;

This line is very important. this.childComponentRef is a private property on the service and is accessed by the removeComponent() public method. As we talked earlier, only one modal window is shown at a time to the user, which implies that only one component can exist in the #modal-container . This component, upon creation, is stored in the this.childComponentRef variable. You can think of this variable as the current-active-modal-component in your application.

The last line in this method, document.getElementById(parentId).appendChild(childDomElem) appends the component into the #parentId div.

The second public method is the removeComponent() method. This method destroys the current-active-modal-component. It also removes it from the component tree so that angular knows not to check it when change detection occurs. To understand change detection, I would recommend this article by Pascal Precht.

The next service we will look at is the ModalService .

modal.service.ts

This service is pretty simple. It has two public methods again namely:

1. init()

2. destroy()

The init() method initialises the modal window taking 3 inputs namely:

component inputs outputs

The init method appends the component to the DOM and the Angular component tree using the DomService. Then, we show the modal and the overlay by using the .show class.

The destroy() method destroys the component and hides the modal and overlay.

This wraps up the major part of the setup.

EntryComponents

One other thing that we should not forget is to add the SampleComponent in the entryComponents of the module.

app.module.ts

The entryComponents is used to define the components that are not found in html initially and that are created dynamically with ComponentFactoryResolver . In order for angular to compile, it needs this hint in the module. Since our SampleComponent will be dynamically added to the DOM, we need to mention it in the NgModule decorator.

Putting all this to use

Here I will show you how to use the new modal service you created. All you need to do is to import the ModalService into the component you wish to show the modal from. Then just call the init() method on the service and pass the component you want to show. Its just that simple now.

You can pass the inputs/outputs to the component as the second and third arguments. I passed an input object here in this example.

Responsiveness

To make the modals responsive, you can do it with media queries easily. I can talk about responsiveness in another article but its pretty simple and you can find plenty of resources online how to do that.

Conclusion

Remember that the point of all this effort was to not import a full-fledged modal library that may have bugs or a lot of extra overhead that you might not need in your application. This way you can expand on your mini-modal library as the requirements change.

I hope this was helpful for you guys. Cheers!