Skip to content
This repository was archived by the owner on Nov 4, 2020. It is now read-only.
Harris Schneiderman edited this page Sep 7, 2017 · 4 revisions

Modals

What is needed?

Modals consist of two things: the modal trigger and the modal dialog.

Modal Trigger

The modal trigger should always be a button element. It requires a data-dialog-id attribute which should be the id of the modal that it triggers. For example, a modal with id="my-modal" should have a trigger with data-dialog-id="my-modal"

The modal dialog

The modal dialog should consist of the following:

  • the "dqpl-modal" class
  • role="dialog"
  • and id for the trigger to point at in it's data-dialog-id attribute
  • Within the <div class="dqpl-modal" role="dialog"></div> element:
    • An element with the "dqpl-dialog-inner" class
    • Within "dqpl-dialog-inner":
      • An element with the "dqpl-modal-header" which consists of the modal's heading and the close button
        • The close button should be a <button /> element with the "dqpl-modal-close" class
    • A sibling of "dqpl-modal-header" should be an element with the "dqpl-modal-content". This is where all of the modal's content will live.
    • A sibling of the "dqpl-modal-content" element, should be the modal's footer (an element with the class "dqpl-modal-footer").

API

The custom events "dqpl:dialog:aria-hide" and "dqpl:dialog:aria-show"are available to be trigged on modal elements. "dqpl:dialog:aria-hide" will apply aria-hidden="true" to every thing except the modal (and parents of the modal), while "dqpl:dialog:aria-show" will revert the aria-hidden="true".

In addition, adding the "data-force-action="true" attribute will prevent the dqpl javascript from allowing the modal to be closed via escape keydown.

Also, adding the "data-no-resize="true" attribute will prevent the dqpl javascript from responsively resizing the modal content's height.

const modal = document.querySelector('.dqpl-modal');
const e = new CustomEvent('dqpl:dialog:aria-hidden', {
  bubbles: true,
  cancelable: false
});

modal.dispatchEvent(e);

Example HTML

Simple modal with just text

The main thing to note here, is that the footer just consists of a single "OK" button.

<button class="dqpl-button-secondary" type="button" data-dialog-id="demo-1">Modal with just text</button>
<div class="dqpl-modal" role="dialog" id="demo-1">
  <div class="dqpl-dialog-inner">
    <div class="dqpl-modal-header">
      <h2>Text modal</h2>
      <button class="dqpl-modal-close dqpl-icon" type="button">
        <div class="fa fa-close" aria-hidden="true"></div>
        <div class="dqpl-offscreen">Close</div>
      </button>
    </div>
    <div class="dqpl-modal-content">
      <p>This is a modal with just text in it and stuff.</p>
    </div>
    <div class="dqpl-modal-footer">
      <button class="dqpl-button-secondary dqpl-modal-cancel" type="button">OK</button>
    </div>
  </div>
</div>

Complex modal with a form

The main thing to note here, is that the footer consists of both a "SAVE" and a "CANCEL" button.

<button class="dqpl-button-secondary" type="button" data-dialog-id="demo-2">Modal with form</button>
<div class="dqpl-modal" role="dialog" id="demo-2">
  <div class="dqpl-dialog-inner">
    <div class="dqpl-modal-header">
      <h2>Modal with form</h2>
      <button class="dqpl-modal-close" type="button">
        <div class="fa fa-close" aria-hidden="true"></div>
        <div class="dqpl-offscreen">Close</div>
      </button>
    </div>
    <div class="dqpl-modal-content">
      <div class="field-section" role="group" aria-labelledby="personal-info">
        <h3 id="personal-info">Personal information</h3>
        <div class="dqpl-field-wrap">
          <label class="dqpl-label dqpl-required" for="first-name">First name</label>
          <input class="dqpl-text-input" type="text" id="first-name" aria-required="true"/>
          <div class="dqpl-error-wrap"></div>
        </div>
        <div class="dqpl-field-wrap">
          <label class="dqpl-label dqpl-required" for="last-name">Last name</label>
          <input class="dqpl-text-input" type="text" id="last-name" aria-required="true"/>
          <div class="dqpl-error-wrap"></div>
        </div>
      </div>
      <div class="field-section" role="group" aria-labelledby="contact-info">
        <h3 id="contact-info">Contact information</h3>
        <div class="dqpl-field-wrap">
          <label class="dqpl-label dqpl-required" for="email">Email</label>
          <input class="dqpl-text-input" type="text" id="email" aria-required="true"/>
          <div class="dqpl-error-wrap"></div>
        </div>
        <div class="dqpl-field-wrap">
          <label class="dqpl-label dqpl-required" for="phone">Phone number</label>
          <input class="dqpl-text-input" type="text" id="phone" aria-required="true"/>
          <div class="dqpl-error-wrap"></div>
        </div>
      </div>
    </div>
    <div class="dqpl-modal-footer">
      <button class="dqpl-button-primary" type="button">Save</button>
      <button class="dqpl-button-secondary dqpl-modal-cancel" type="button">Cancel</button>
    </div>
  </div>
</div>

Clone this wiki locally