htmx snippets and examples

Table of Contents

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); };"

Resources

Valentino Gagliardi

Hi! I'm Valentino! I'm a freelance consultant with a wealth of experience in the IT industry. I spent the last years as a frontend consultant, providing advice and help, coaching and training on JavaScript, testing, and software development. Let's get in touch!