Go back Web Development

HTML dialog

Simplest setup


<dialog data-dialog-target="dialog" open >
  <div class="bg-red-50 p-5">
    <form method="dialog">
      <button formmethod="dialog">Close</button>
    </form>

    <hr>

    <form src="/foo" method="post">
      <button>Submit</button>
      <button formmethod="dialog">Close</button>
    </form>
  </div>
</dialog>

Stimulus JS open dialog as Modal


// app/javascript/controllers/dialog_controller.js
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="dialog"
export default class extends Controller {
  static targets = [ "dialog" ]
  open() {
    this.dialogTarget.showModal()
    document.body.classList.add("overflow-hidden")
  }

  close() {
    document.body.classList.remove("overflow-hidden")
    this.dialogTarget.close()
  }

  clickOutside(event) {
    if (event.target === this.dialogTarget) {
      this.close();
    }
  }
}

<body>
...

<div data-controller="dialog" data-action="click->dialog#clickOutside">
  <button data-action="click->dialog#open">Open Dialog</button>
  <dialog data-dialog-target="dialog" class=" w-full lg:w-1/3">
    <div class="bg-red-50 p-5">
      <button data-action="click->dialog#close">X</button>

      <form src="/foo" method="post">
        <button>submit</button>
      </form>
    </div>
  </dialog>
</div>

...

</body>

// app/assets/stylesheets/application.css
dialog::backdrop {
  backdrop-filter: blur(10px);
}

alternative: you can style  <dialog class="backdrop:bg-slate-400 backdrop:opacity-80"> with tailwind

Stimulus JS opens dialog non-modally (ideal for dropdowns, searchboxes)



// app/javascript/controllers/dialog_controller.js
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="dialog"
export default class extends Controller {
  static targets = [ "dialog", "open" ]
  open() {
    this.dialogTarget.show()
  }

  close() {
    this.dialogTarget.close()
  }

  clickOutside(event) {
    if (!this.dialogTarget.contains(event.target) && event.target != this.openTarget) {
      this.close();
    }
  }
}

<body data-controller="dialog" data-action="click->dialog#clickOutside">
  <dialog data-dialog-target="dialog" class="w-full md:w-3/4 lg:w-2/3">
    <div class="bg-red-50 p-5">
      <button data-action="click->dialog#close">X</button>

      <form src="/foo" method="post">
        <button>submit</button>
      </form>
    </div>
  </dialog>

  <button data-action="click->dialog#open" data-dialog-target="open">Open Dialog</button>
<body>