Skip to content

Dialog JS ​

scss
@use '@natachah/vanilla-frontend/scss/components/dialog';

Difference between modal and non-modal:

The key difference is the level interaction and interaction restriction. A modal will block interaction with the main content, and they have their own context focus (use of a backdrop). But a non-modal don't impose context and restriction.

Syntax ​

The dialog is using the native <dialog> tag.

You can define if the dialog is a modal with the aria-modal attribute.

html
<button aria-controls="myDialog">Open the dialog</button>
<dialog id="myDialog" aria-modal="true" aria-label="demo">
    Content of the dialog
    <button data-dialog-close>Close the dialog</button>
</dialog>
css
--dialog-color
--dialog-background
--dialog-border-size
--dialog-border-style
--dialog-border-color
--dialog-border-radius
--dialog-padding-inline
--dialog-padding-block
--dialog-position
--dialog-width
--dialog-height
--dialog-max-width
--dialog-max-height
--dialog-index
--dialog-backdrop-background
--dialog-backdrop-filter
--dialog-open-animation
--dialog-open-transform
--dialog-close-animation
--dialog-close-transform
--dialog-divider-size
--dialog-divider-style
--dialog-divider-color
js
import Dialog from "@natachah/vanilla-frontend/js/_dialog"
const myDialog = document.getElementById('myDialog')
if (myDialog) new Dialog(myDialog)

To work properly you must have a <button> in your page with the attribute aria-controls="IdOfDialogToOpen" that will open the dialog.

And inside your <dialog> you should have a <button> with the attribute data-dialog-close to close the dialog.

For accessibility, don't forget to add a aria-labelledby into the <dialog> to set a title.

Layout ​

The dialog can have a <header> and/or <footer> inside to create a more complexe layout.

html
<dialog id="layoutDialog" aria-labelledby="layoutDialogTitle" aria-modal="true">
    <header id="layoutDialogTitle">This is a header</header>
    <div>
        <p>This is the content</p>
        <button data-dialog-close>Close</button>
    </div>
    <footer>This is a footer</footer>
</dialog>

Form ​

You can submit a <form> inside the <dialog>.

html
<dialog id="formDialog" aria-labelledby="formDialogTitle" aria-modal="true">
    <h3 id="formDialogTitle">Dialog with form</h3>
    <form method="POST">
        <label for="animal">What is your favorite animal</label>
        <input id="animal" type="text" name="animal" required>
        <button type="reset" data-dialog-close>Cancel</button>
        <button type="submit">Default submit</button>
    </form>
</dialog>

If you want to submit via javascript add the method="dialog" attribute on the <form> or the formmethod="dialog" attribute on the <button>.

Then you should use the event dialog:submited to catch the values.

html
<button aria-controls="jsDialog">Open the dialog</button>
<dialog id="jsDialog" aria-labelledby="jsDialogTitle" aria-modal="true">
    <h3 id="jsDialogTitle">Dialog with form</h3>
    <form method="dialog">
        <label for="animal">What is your favorite animal</label>
        <input id="animal" type="text" name="animal" required>
        <button type="reset" data-dialog-close>Cancel</button>
        <button type="submit">Javascript submit</button>
    </form>
</dialog>
<p>Your favorite animal is: <span id="favorite">--</span></p>
js
const demoDialogFormJS = document.getElementById('jsDialog')

if (demoDialogFormJS) {

    // Init the dialog
    new Dialog(demoDialogFormJS)

    // Check for the dialog:submited event
    demoDialogFormJS.addEventListener('dialog:submited', (e) => {
        const value = e.detail.form.querySelector('input').value
        document.getElementById('favorite').innerText = value
    })

}

Javascript ​

To work properly the dialog required some javascript.

Methods ​

MethodDescription
open(e)This method will open the dialog
close()This method will close the dialog
submit()This method will submit the dialog

Events ​

Event nameDescriptionValue
dialog:openingWhen the method open() is called–
dialog:openedAfter the method open() is called–
dialog:closingWhen the method close() is called–
dialog:closedAfter the method close() is called–
dialog:submitingWhen the method submit() is calledform as an HTMLElement
dialog:submitedAfter the method submit() is calledform as an HTMLElement
js
// E.G. basic opening
document.getElementById('myDialogID').addEventListener('dialog:opening', () => {
    console.log('The dialog is opening')
})

// E.G. with form value
document.getElementById('myDialogID').addEventListener('dialog:submited', (e) => {
    const theHTMLForm = e.detail.form
    console.log('The dialog is submited')
})

Released under the MIT License.