#htmx #html #frontend

Day 9: Client-Side Scripting

Welcome to Day 9. htmx reduces JS, but doesn’t ban it.

Sometimes you need to clear an input after a message is sent, or close a modal.

htmx:afterSwap

Listen for htmx events in standard JS.

<script>
    document.body.addEventListener('htmx:afterSwap', function(evt) {
        if(evt.detail.target.id === 'chat-window') {
            document.getElementById('msg-input').value = '';
        }
    });
</script>

Alpine.js Integration

Alpine pairs perfectly with htmx for “local” state (like toggling a dropdown) that doesn’t need a server roundtrip.

<!-- Data from htmx, Toggle logic by Alpine -->
<div x-data="{ open: false }">
    <button @click="open = !open">Toggle</button>
    
    <div x-show="open" hx-get="/content" hx-trigger="load">
        Loading...
    </div>
</div>

_hyperscript

Created by the htmx author. It’s like AppleScript for the web. Readable, embeddable.

<button hx-post="/save" 
        _="on htmx:afterRequest reset() me">
  Save
</button>

Challenge for Day 9

  1. Create a modal using <dialog>.
  2. Open it with a button.
  3. Inside, have a form that submits via htmx.
  4. On successful submission, the server returns “Success”, and the modal should close automatically after 1 second.

Solution (Vanilla JS approach):

<dialog id="my-modal">
    <form hx-post="/submit" hx-target="#result">
        ...
    </form>
    <div id="result"></div>
</dialog>

<script>
    document.getElementById('my-modal').addEventListener('htmx:afterSwap', (e) => {
        // If the server returned our success marker
        if(e.target.innerHTML.includes('Success')) {
            setTimeout(() => e.target.closest('dialog').close(), 1000);
        }
    });
</script>

Tomorrow: Validation.