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>
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.&padFragment=rows names the fragment outright - for a
target without an id (hx-target="closest tr", this) or a part other
than the target.$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.$padCsrf on, a post needs the session's token. A {form} carries it;
for an hx-post on anything else put it on the body once:
<body hx-headers="{^headers}"> with
$headers = [ 'X-CSRF-Token' => padCsrfToken () ].rules= posted through htmx comes back as its own fragment -
refilled, with PAD's messages - and with client the browser checks the same
rules first (Client validation).hx-swap-oob="true" go where their id is: the
count in the header, a summary beside a list.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.