-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Docs: HTML Dialog Example #3604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| +++ | ||
| title = "Modal Dialogs with HTML Dialogs" | ||
| template = "demo.html" | ||
| +++ | ||
|
|
||
| Since 2022 the HTML spec has included a `<dialog>` tag and it works well with | ||
| htmx. Consider the following html: | ||
|
|
||
| ```html | ||
| `<button | ||
| class="btn primary" | ||
| hx-get="/modal" | ||
| hx-target="#modal-placeholder" | ||
| hx-swap="outerHTML" | ||
| >Open Modal</button> | ||
|
|
||
| <div id="modal-placeholder"></div> | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My intuition tells me there should be an easier way to do this, without needing this place holder div. But without, there's nothing to do an "outerHTML" swap with. And without that "outerHTML" swap, the I think for Locality-of-behavior reasons, it's best to have the call to |
||
| ``` | ||
|
|
||
| This button sends a `GET` request to `/modal` when the button is clicked. The | ||
| server then responds with with a dialog that get swapped into an empty `<div>`. | ||
| The `<dialog>` looks like this: | ||
|
|
||
| ```html | ||
| <dialog id="modal-dialog" hx-on::after-settle="this.showModal()"> | ||
| <h1>Modal Dialog</h1> | ||
| This is the modal content. You can put anything here, like text, | ||
| or a form, or an image. | ||
| <br/> | ||
| <br/> | ||
| <button class="btn danger" hx-get="/close" hx-target="#modal-dialog" hx-swap="outerHTML">Close</button> | ||
| </dialog>` | ||
| ``` | ||
|
|
||
| Note the use of `hx-on::after-settle`. This is needed because in order for the dialog to actually be shown, | ||
| the `showModal` function must be called. | ||
|
|
||
| The close button fetches an empty `div` via the `/close` route to replace the dialog when it's closed: | ||
|
|
||
| ```html | ||
| <div id="modal-holder"></div> | ||
|
klnusbaum marked this conversation as resolved.
Outdated
|
||
| ``` | ||
|
|
||
| This essentially "resets" the page, and clicking the button again will open a new dialog. | ||
|
|
||
| {{ demoenv() }} | ||
|
|
||
| <div id="modal-placeholder"></div> | ||
|
|
||
| <style> | ||
| dialog { | ||
| margin: auto; | ||
| padding: 1em; | ||
| border: 0; | ||
| } | ||
| </style> | ||
|
|
||
| <script> | ||
|
|
||
| //========================================================================= | ||
| // Fake Server Side Code | ||
| //========================================================================= | ||
|
|
||
| // routes | ||
| init("/demo", function(request, params) { | ||
| return `<button | ||
| class="btn primary" | ||
| hx-get="/modal" | ||
| hx-target="#modal-placeholder" | ||
| hx-swap="outerHTML" | ||
| >Open Modal</button> | ||
| `}) | ||
|
|
||
| onGet("/modal", function(request, params){ | ||
| return `<dialog id="modal-dialog" hx-on::after-settle="this.showModal()"> | ||
| <h1>Modal Dialog</h1> | ||
| This is the modal content. You can put anything here, like text, | ||
| or a form, or an image. | ||
| <br/> | ||
| <br/> | ||
| <button class="btn danger" hx-get="/close" hx-target="#modal-dialog" hx-swap="outerHTML">Close</button> | ||
| </dialog>` | ||
| }) | ||
|
|
||
| onGet("/close", function(request, params){ | ||
| return `<div id="modal-placeholder"></div>` | ||
| }) | ||
| </script> | ||
Uh oh!
There was an error while loading. Please reload this page.