| HTMX Demos | ||||||||||||||||||||||||||
HTMX — 10 Essential PatternsInteractive demonstrations of the most useful HTMX UI patterns. Each panel shows a live demo alongside the relevant HTMX markup. 1. Click to Edit↗ htmx.org/examples/click-to-editInline editing — a view block swaps to a form on demand, then back on save or cancel. Live Demo
HTMX Markup <!-- View mode -->
<div id="contact">
<p>Ada Lovelace</p>
<button
hx-get="/contact/edit"
hx-target="#contact"
hx-swap="outerHTML">
Edit
</button>
</div>
<!-- Edit form (server response) -->
<form
hx-put="/contact"
hx-target="#contact"
hx-swap="outerHTML">
<input name="name" value="Ada"/>
<button type="submit">Save</button>
<button hx-get="/contact"
hx-target="#contact"
hx-swap="outerHTML">
Cancel
</button>
</form>
2. Bulk Update↗ htmx.org/examples/bulk-updateSelect multiple rows with checkboxes and update their status in a single request. Live Demo
HTMX Markup <form
hx-put="/users/activate"
hx-target="#users-table"
hx-swap="outerHTML">
<table id="users-table">
<tr>
<td>
<input type="checkbox"
name="ids"
value="1"/>
</td>
<td>Alan Turing</td>
<td>Inactive</td>
</tr>
<!-- more rows ... -->
</table>
<button type="submit">
Activate Selected
</button>
</form>
3. Click to Load↗ htmx.org/examples/click-to-loadLoad additional rows on demand — a "Load More" button appends content without reloading. Live Demo HTMX Markup <tbody id="contacts">
<!-- existing rows -->
<tr>...</tr>
<!-- trigger row at the bottom -->
<tr id="load-more-row">
<td colspan="3">
<button
hx-get="/contacts?page=2"
hx-target="#load-more-row"
hx-swap="outerHTML"
hx-indicator="#spinner">
Load More
</button>
<span id="spinner"
class="htmx-indicator">
Loading...
</span>
</td>
</tr>
</tbody>
4. Delete Row↗ htmx.org/examples/delete-rowIssue a DELETE request and swap the target element with an empty string to remove it. Live Demo Mercury
Venus
Earth
Mars
Jupiter
Saturn
HTMX Markup <tr id="row-mercury">
<td>Mercury</td>
<td>
<button
hx-delete="/planet/mercury"
hx-target="closest tr"
hx-swap="outerHTML"
hx-confirm="Delete Mercury?">
Delete
</button>
</td>
</tr>
<!-- Server returns HTTP 200 + -->
<!-- empty body; htmx removes -->
<!-- the element automatically -->
5. Inline Validation↗ htmx.org/examples/inline-validationValidate fields on blur by posting to the server; the response replaces the error element. Live Demo HTMX Markup <input
name="username"
hx-post="/validate/username"
hx-trigger="blur"
hx-target="#username-error"
hx-swap="innerHTML"/>
<div id="username-error"></div>
<!-- Server returns: -->
<!-- "" (empty) = valid -->
<!-- "<span>Taken</span>" = error -->
<!-- Or validate as-you-type: -->
<input
hx-trigger="keyup changed
delay:300ms"
.../>
6. Active Search↗ htmx.org/examples/active-searchPost the search query on every keystroke (debounced) and replace the results container. Live Demo HTMX Markup <input
type="search"
name="q"
placeholder="Search..."
hx-post="/search"
hx-trigger="keyup changed
delay:300ms"
hx-target="#results"
hx-indicator="#spinner"/>
<span id="spinner"
class="htmx-indicator">
Searching...
</span>
<div id="results">
<!-- server renders matched rows -->
</div>
7. Progress Bar↗ htmx.org/examples/progress-barStart a job, then poll the server for status updates to drive a progress indicator. Live Demo
Idle
0%
Press Start to run the job. HTMX Markup <!-- 1. Start the job -->
<button
hx-post="/start-job"
hx-target="#progress">
Start
</button>
<!-- 2. Poll for updates -->
<div id="progress"
hx-get="/job-status"
hx-trigger="every 600ms"
hx-target="this"
hx-swap="outerHTML">
<div style="width:0%"></div>
</div>
<!-- When done, server omits -->
<!-- hx-trigger to stop polling -->
8. Infinite Scroll↗ htmx.org/examples/infinite-scrollWhen the last row becomes visible in the viewport, automatically fetch and append the next page. Live Demo — scroll the list Loaded 10 items HTMX Markup <tbody id="contacts">
<!-- normal rows -->
<tr>...</tr>
<!-- last row triggers on reveal -->
<tr
hx-get="/contacts?page=2"
hx-trigger="revealed"
hx-swap="afterend"
hx-target="this">
<td>...</td>
</tr>
</tbody>
<!-- hx-trigger="revealed" fires -->
<!-- when element enters viewport -->
9. Value Select↗ htmx.org/examples/value-selectCascading dropdowns — changing the first select fetches and populates the second from the server. Live Demo HTMX Markup <select
name="category"
hx-get="/models"
hx-target="#model-select"
hx-trigger="change"
hx-include="[name='category']">
<option value="llm">Language</option>
<option value="img">Image</option>
</select>
<!-- Populated dynamically -->
<select id="model-select">
<!-- server renders <option>s -->
</select>
10. Lazy Load↗ htmx.org/examples/lazy-loadDefer expensive content — the placeholder loads its real content when it scrolls into view. Live Demo
⏳ Content will load lazily when revealed…
In production this fires automatically via HTMX Markup <!-- Placeholder with lazy trigger -->
<div
hx-get="/expensive-widget"
hx-trigger="revealed"
hx-swap="outerHTML">
<!-- shown while waiting -->
<div class="htmx-indicator">
Loading...
</div>
</div>
<!-- Server responds with content -->
<div class="widget">
... rendered chart / data ...
</div>
<!-- Use hx-trigger="load" for -->
<!-- immediate deferred loading -->
|
||||||||||||||||||||||||||