htmx snippets and examples
htmx event listeners
Colon vs double-colon
Use case
Listening for htmx-specific events and DOM events on the same element.
Code
<dialog hx-on:keydown="// do something here"
hx-on::after-swap="// do something here">
<!-- some other element here -->
</dialog>
Explanation
In htmx we can listen for DOM events with the following syntax:
hx-on:keydown="// do something here"
Notice the colon between hx-on
and the event name.
In contrast, listening to htmx-specific events such as afterSwap
requires the double colon:
hx-on::after-swap="// do something here"
Resources
htmx with the HTML dialog element
Opening a dialog, removing HTML dialog children elements on Esc, on close
Use case
An HTML <dialog>
element modal that gets opened after htmx swap and that is able to remove its children elements on Esc and close.
Code
<!-- Trigger element -->
<a href="/book/{id}/" hx-get="/book/{id}/" hx-target="#dialog" hx-swap="beforeend">The naked sun</a>
<!-- Dialog -->
<dialog id="dialog"
hx-on:keydown="if (event.key === 'Escape' || event.key === 'Esc') { disposeElements.call(this); };"
hx-on::after-swap="this.showModal();">
<form method="dialog" hx-on:submit="disposeElements.call(this);">
<button>Close the dialog</button>
</form>
<div id="content">
<p>some content</p>
<div>
<p>(possibly with other elements nested) here</p>
</div>
</div>
</dialog>
<script>
function disposeElements() {
return this.closest('dialog').querySelector('#content')?.remove();
}
</script>
Explanation
This dialog is always present in the DOM, but initially hidden as per the default. When the user clicks the trigger element, htmx swaps the partial HTML received from the endpoint declared in hx-get
, and puts the content into the dialog.
After the swap, the modal opens itself:
hx-on::after-swap="this.showModal();"
Please note that using showModal()
is preferred over the open
attribute of the dialog since modals opened with showModal()
can be closed with Esc.
When the user closes the dialog by clicking <button>Close the dialog</button>
, the modal closes via method="dialog"
on the form
element. This triggers a submit
event on the form, where we dispose of the content:
hx-on:submit="disposeElements.call(this);"
When the user closes the dialog by pressing the Esc key, this triggers a keydown
event where we dispose of the content:
hx-on:keydown="if (event.key === 'Escape' || event.key === 'Esc') { disposeElements.call(this); };"