+++ title = "Dialogs" template = "demo.html" +++ htmx provides several approaches for working with modals and dialogs, from simple browser-native dialogs to custom implementations and framework integrations. **Jump to:** 1. [Browser Native Dialogs](#browser-native-dialogs) 2. [Custom Modal Dialogs](#custom-modal-dialogs) 3. [Bootstrap Modals](#bootstrap-modals) 4. [UIKit Modals](#uikit-modals) ## Browser Native Dialogs The simplest approach uses the [`hx-confirm`](@/attributes/hx-confirm.md) attribute to trigger native browser dialogs. These are triggered by the user interaction that would trigger the AJAX request, but the request is only sent if the dialog is accepted. ```html
``` ## Custom Modal Dialogs While htmx works great with dialogs built into CSS frameworks (like Bootstrap and UIKit below), htmx also makes it easy to build modal dialogs from scratch. Here is a quick example of one way to build them. Click here to see a demo of the final result: ### High Level Plan We're going to make a button that loads remote content from the server, then displays it in a modal dialog. The modal content will be added to the end of the `` element, in a div named `#modal`. In this demo we'll define some nice animations in CSS, and then use some [Hyperscript](https://hyperscript.org) to remove the modals from the DOM when the user is done. Hyperscript is *not* required with htmx, but the two were designed to be used together and it is much nicer for writing async & event oriented code than JavaScript, which is why we chose it for this example. ### Main Page HTML ```html ``` ### Modal HTML Fragment ```html ``` ### Custom Stylesheet ```css /***** MODAL DIALOG ****/ #modal { /* Underlay covers entire screen. */ position: fixed; top:0px; bottom: 0px; left:0px; right:0px; background-color:rgba(0,0,0,0.5); z-index:1000; /* Flexbox centers the .modal-content vertically and horizontally */ display:flex; flex-direction:column; align-items:center; /* Animate when opening */ animation-name: fadeIn; animation-duration:150ms; animation-timing-function: ease; } #modal > .modal-underlay { /* underlay takes up the entire viewport. This is only required if you want to click to dismiss the popup */ position: absolute; z-index: -1; top:0px; bottom:0px; left: 0px; right: 0px; } #modal > .modal-content { /* Position visible dialog near the top of the window */ margin-top:10vh; /* Sizing for visible dialog */ width:80%; max-width:600px; /* Display properties for visible dialog*/ border:solid 1px #999; border-radius:8px; box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.3); background-color:white; padding:20px; /* Animate when opening */ animation-name:zoomIn; animation-duration:150ms; animation-timing-function: ease; } #modal.closing { /* Animate when closing */ animation-name: fadeOut; animation-duration:150ms; animation-timing-function: ease; } #modal.closing > .modal-content { /* Animate when closing */ animation-name: zoomOut; animation-duration:150ms; animation-timing-function: ease; } @keyframes fadeIn { 0% {opacity: 0;} 100% {opacity: 1;} } @keyframes fadeOut { 0% {opacity: 1;} 100% {opacity: 0;} } @keyframes zoomIn { 0% {transform: scale(0.9);} 100% {transform: scale(1);} } @keyframes zoomOut { 0% {transform: scale(1);} 100% {transform: scale(0.9);} } ``` ## Bootstrap Modals Many CSS toolkits include styles (and Javascript) for creating modal dialog boxes. This example shows how to use htmx alongside original JavaScript provided by Bootstrap. We start with a button that triggers the dialog, along with a DIV at the bottom of your markup where the dialog will be loaded: ```html ``` This button uses a `GET` request to `/modal` when this button is clicked. The contents of this file will be added to the DOM underneath the `#modals-here` DIV. The server responds with a slightly modified version of Bootstrap's standard modal: ```html ``` ## UIKit Modals This example shows how to use htmx to display dynamic dialogs using UIKit, and how to trigger its animation styles with little or no Javascript. This is an example of using htmx to remotely load modal dialogs using UIKit. In this example we will use [Hyperscript](https://hyperscript.org) to demonstrate how cleanly that scripting language allows you to glue htmx and other libraries together. ```html
``` This button uses a `GET` request to `/uikit-modal.html` when this button is clicked. The contents of this file will be added to the DOM underneath the `#modals-here` DIV. Rather than using the standard UIKit Javascript library we are using a bit of Hyperscript, which triggers UIKit's smooth animations. It is delayed by 10ms so that UIKit's animations will run correctly. Finally, the server responds with a slightly modified version of UIKit's standard modal: ```html ``` Hyperscript on the button and the form trigger animations when this dialog is completed or canceled. If you didn't use this Hyperscript, the modals will still work but UIKit's fade in animations will not be triggered. You can, of course, use JavaScript rather than Hyperscript for this work, it's just a lot more code: ```javascript // This triggers the fade-in animation when a modal dialog is loaded and displayed window.document.getElementById("showButton").addEventListener("htmx:afterOnLoad", function() { setTimeout(function(){ window.document.getElementById("modal").classList.add("uk-open") }, 10) }) // This triggers the fade-out animation when the modal is closed. window.document.getElementById("cancelButton").addEventListener("click", function() { window.document.getElementById("modal").classList.remove("uk-open") setTimeout(function(){ window.document.getElementById("modals-here").innerHTML = "" }, 200) }) ```