How To Create a Customizable Modal in Vanilla JavaScript

How To Create a Customizable Modal in Vanilla JavaScript

In less than 50 lines of code
Ferenc Almasi β€’ 2023 July 28 β€’ Read time 7 min read
Learn how you can create a customizable modal in JavaScript with the ability to customize text and buttons in less than 50 lines of code.
  • twitter
  • facebook
JavaScript

Modals are often a core part of interactive web applications. They appear on top of the existing page after a user action, often accompanied by a backdrop to draw attention to the popup and ask for further actions from the user, such as confirmation, like deleting information.

In this tutorial, we'll take a look at how to create a customizable modal in vanilla JavaScript using the dialog element introduced in HTML5.


To make the modal customizable, we want to be able to set a couple of different options when creating one. To create a modal, we need to call a function with a set of parameters that will customize the appearance and behavior of the modal:

Copied to clipboard! Playground
const confirmDialog = modal({
    id: 'confirmModal',
    title: 'Are you sure?',
    text: 'All your changes will be deleted...',
    buttons: [
        {
            title: 'Cancel',
            type: 'secondary'
        },
        {
            title: 'Yes, I\'m sure',
            type: 'primary',
            callback: () => {
                console.log('Delete confirmed...')
            }
        }
    ]
})

// Then later in the application, call whenever we need it
confirmDialog.showModal()
Example of how creating modal will work

We'll accept four different parameters for various purposes:

  • id: A unique ID that we can use to identify the modal. It'll be used as the id of the element that will be created by the modal function.
  • title: The title of the modal, displayed in bold using a b tag.
  • text: The content of the modal displayed in a paragraph.
  • buttons: An array of objects that define the buttons of the modal from left to right.

Each button can have three different properties: a title for the button text, a type that can be either primary or secondary, and a callback function that will be executed on click. If no callback property is present, the button will function as a close button.

πŸ” Login to get access to the full source code in one piece. With CSS included.

Now that we know how we want the modal to behave, let's take a look at the actual function. Create a new function called modal and add the following code to create the HTML that will be rendered:

Copied to clipboard! Playground
const modal = config => {
    const {
        id,
        title,
        text,
        buttons
    } = config

    const html = `
        <dialog id="${id}">
            <b>${title}</b>
            <p>${text}</p>
            <div>
                ${buttons.map(button => `
                    <button class="${button.type}">
                        ${button.title}
                    </button>
                `).join('')}
            </div>
        </dialog>
    `
}
modal.js
Create the HTML layout for the modal

Using destructuring assignment, we can extract the values from the config parameters to use them individually where necessary. With a template literal, we can build the HTML layout for the modal.

Note that we've utilized a dialog element, which adds native modal functionality to our function.

Inside the dialog, we display the title and text, along with the buttons. To generate a button for each entry, we use the map method to loop through the array. When using map, remember to join the generated array into a single string using the join method. To add this HTML to the document when the function is called, append the following code after the html variable:

Copied to clipboard! Playground
const parser = new DOMParser().parseFromString(html, 'text/html')
const dialog = parser.querySelector('dialog')

document.body.appendChild(dialog)

return dialog
modal.js
Append the dialog to the document

Using a DOMParser, we can convert the string into a set of DOM elements, which can be appended to the end of the body.

Alternatively, you can also call appendChild only when the modal is shown. This way, you'll add the modal's HTML to the page only when the user interacts with the page to trigger a modal, thus improving the initial page load.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScriptinfo Remove ads

Last but not least, we need to attach event listeners to the buttons inside the modal. Add the following lines of code before appending the dialog to the document:

Copied to clipboard! Playground
const buttonElements = dialog.querySelectorAll('button')

buttonElements.forEach((button, index) => {
    button.addEventListener('click', () => {
        buttons[index].callback?.()
        dialog.close()
    })
})

document.body.appendChild(dialog)

return dialog
modal.js
Adding event listeners to buttons

This code will loop through each button inside the dialog and attach an event listener using addEventListener. Inside click event callback, we can reference the passed callback function using buttons[index].callback.

Make sure to use optional chaining to avoid errors for buttons without a callback.

After the callback has been executed, we can call dialog.close to close the dialog with all actions. By combining this with the optional chaining from the previous line, we can allow developers to omit the callback property on a button to make it act as a close functionality.

πŸ” Login to get access to the full source code in one piece. With CSS included.

Triggering the Modal

To trigger the modal, we can call the showModal method on the return value of the modal function. This is because the function returns the dialog element at the end.

Copied to clipboard! Playground
// Available methods on the returned dialog:
const dialog = modal({ ... })

dialog.show()      // Opens the modal (allow interaction outside the modal)
dialog.showModal() // Opens the modal (prevents interaction outside the modal)
dialog.close()     // Closes the modal
dialog.open        // Returns a boolean whether the modal is open or not
Available methods on the variable

The dialog elements come with native modal functionality that we can use to show and hide the modal. It has two types of show functionality:

  • show: Opens the modal while allowing interaction with content outside the modal.
  • showModal: Opens the modal while preventing interaction with content outside the modal.

It also has an open property that can be used to verify if the modal is currently open or not. It returns a boolean false if the modal is closed; otherwise, it returns true.


Summary

In summary, creating a customizable modal in vanilla JavaScript can be broken down into three main steps:

  • Creating the HTML for the modal using a dialog element
  • Attaching event listeners to buttons and forwarding functions as a callback
  • Appending the dialog to the document, and returning the element from the function

If you would like to learn more about dialogs in HTML, be sure to check out the following tutorial, where we also take a look at how you can create simple dialogs without the use of any JavaScript.

How to Create Native Interactive Modals in HTML
  • twitter
  • facebook
JavaScript
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.