bigskysoftware / htmx

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

HX-boost but only replacing parts of the page #983

Open svezina opened 2 years ago

svezina commented 2 years ago

Hi all,

Is there a way, while doing full page hx-boost requests, to get it to only change specific targets in the DOM, even though the response contains the whole page?

In other words, let's say I'm in this situation:

Is there a way to accomplish that? I couldn't find a way in the documentation.

This is something that can be done with Pjax. The Pjax library has an "elements" option that is the equivalent to hx-boost, but it also has a "selectors" option where you can give it a list of ids where the content has to be replaced.

Thanks!

David-Guillot commented 2 years ago

Hi there, have you tried hx-select ?

svezina commented 2 years ago

Hi there, have you tried hx-select ?

I just did. Thanks for the help. I managed to get a bit further in the process. With a combination of hx-boost, hx-select and hx-disinherit, I was able to almost get the desired behavior:

<body hx-boost="true" hx-target="#main" hx-select="#main">
    <div id="stuff_i_dont_want_to_change" hx-disinherit="hx-select hx-target">
        <div id="my_open_chat_windows"></div>
        <div id="my_sidebar"></div>
    </div>
    <nav>
        <a href="/home/>Home</a>
        <a href="/page/>Page</a>
    </nav>
    <div id="#main">
    </div>
</body>

This worked mostly fine, but, unfortunately, when I used the back button, or did a refresh, the #main div would show for a millisecond and disappear.

By adding these meta tags in the head, I managed to get the reloads to work fine:

<meta name="htmx-config" content='{"historyCacheSize": 0, "refreshOnHistoryMiss": true}'>
<meta name="Cache-Control" content="no-cache">

But the back button still blanks my #main div. I'm going to keep trying but if anyone has tips and tricks I'd be curious.

Thanks

1cg commented 1 year ago

Hmmm, that should be working. hx-select is the way to accomplish what you want.

croxton commented 1 year ago

You just need to swap the outerHTML of #main in the response into the #main in the requesting page. Like this:

<body hx-boost="true" hx-target="#main" hx-select="#main" hx-swap="outerHTML">