Htmx
htmx asks the server for a part of the page and swaps the answer in - HTML over the wire, no JavaScript of your own. A PAD template already has names on its parts: every {fragment} can be asked for alone, so the template that renders the first visit also answers every question htmx asks after it.
<input name="q" hx-get="?products" hx-trigger="input changed delay:300ms" hx-target="#results">
<ul id="results">
{fragment 'results'}
{products}<li>{$name}</li>{/products}
{/fragment}
</ul>
Which part answers
-
By the target. htmx sends the id of the element it swaps in
HX-Target; a request of htmx that names no fragment itself gets the fragment called like that element, when the page has one - and the whole page when it has none. -
By the address.
&padFragment=rowsnames the fragment outright - for a target without an id (hx-target="closest tr",this) or a part other than the target. -
By the PHP.
$padFragmentOnly = 'row'decides in the page's PHP. A fragment inside a loop answers with the first row it renders: narrow the rows to the one asked for.
Posts and forms
- With
$padCsrfon, a post needs the session's token. A {form} carries it; for anhx-poston anything else put it on the body once:<body hx-headers="{^headers}">with$headers = [ 'X-CSRF-Token' => padCsrfToken () ]. - A {form} with
rules=posted through htmx comes back as its own fragment - refilled, with PAD's messages - and withclientthe browser checks the same rules first (Client validation). - Elements of an answer marked
hx-swap-oob="true"go where their id is: the count in the header, a summary beside a list.
Pushed by the server
padSse() (Server sent events) streams events; with htmx's sse extension (hx-ext="sse" sse-connect="?ticker") every event's HTML is swapped in as it arrives.
The htmx application shows all of it, each example with its template and PHP: htmx - active search, lazy loading, infinite scroll, inline editing, forms, out-of-band updates and server-sent events.