bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
37.14k stars 1.25k forks source link

feature request: hx-refresh response header to support partial refreshes of selector / targets #745

Closed ptrthomas closed 2 years ago

ptrthomas commented 2 years ago

In server-side frameworks, when you handle an incoming request, it is non-trivial to "switch" the response template processing to another or "append" one or more hx-oob-swap chunks of HTML. It would be way more easier and "generic" to just emit a header and let HTMX do the heavy-lifting, at the expense of extra HTTP request cycles.

This is the pattern I'm using currently which works great. I really think it should be supported out of the box. I also think if multiple "instances" of hx-refresh headers are processable in the same response, this will be even more powerful.

This is my server-code, that signals the client side to refresh only a particular DOM element by id:

if (session.selectedTab === 'script') {
  response.header('hx-trigger', utils.toJson({'ka:refresh': {target: '#main-tabs', path: 'main-tabs'}}));
}

And on the client-side:

htmx.on('ka:refresh', function (evt) {
  let value = evt.detail;
  if (value && value.path && value.target) {
    let target = htmx.find(value.target);
    if (target.getAttribute('hx-swap') === 'outerHTML') {
      target = target.parentElement;
    }
    htmx.ajax('GET', value.path, target);
    document.body.classList.remove('htmx-request');
  }
});

possibly an improvement over the above code is to make the method and parameters dynamic also.

EDIT: another proposal (which I need and which I think solves a common use-case) is to pass this event on to a given "target" element that has hx-trigger set to fire. This is great because then form-parameters and hx-vals will be "naturally" handled. I would greatly appreciate an example if this is already possible out-of-the-box as I couldn't figure this out.

note the last-line removal of the body class is something I consider an existing bug with the JS API htmx.ajax() because it always assumes the body as being the target.

ptrthomas commented 2 years ago

wow I was over thinking this. just realized that the hx-trigger response header combined with something like hx-trigger="ka:refresh-tabs from:body" in the HTML does exactly what I want out of the box !!