bigskysoftware / htmx

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

Let oob use innerHTML for source (and outerHTML for target) #423

Closed guettli closed 10 months ago

guettli commented 3 years ago

I want to use hx-swap-oob to replace a table row of the existing page "out of band".

HTML already in browser (target):

<table>
 <tr id="offer_1">....</tr>
 <tr id="offer_2">....</tr> (old)
 <tr id="offer_3">....</tr>
</table>

I want to add this new table row (source coming from server)

 <tr id="offer_2" class="some-new-css-class"> .... </tr> (new)

Up to now hx-swap-oob does take the outerHTML from the source.

I would like to take the innerHTML, because of one reason:

On the server I have a method to create the table row. This method should not know the fact that result of the method gets used in hx-swap-oob.

I am willing to provide a pull request.

Up to now I am unsure about how solution should look like at the end.

Here is one of many options:

<table hx-swap-oob="innerHTML-source">
 <tr id="offer_2" class="some-new-css-class"> .... </tr> (new)
</table>

innerHTML-source tells htmx to ignore the

tag and take the innerHTML as source.

Would you accept a PR?

BTW, #422 would be nice, too (Docs about how to create a PR).

1cg commented 3 years ago

I'm open to the idea. Maybe use the https://htmx.org/attributes/hx-select/ attribute in conjunction w/ the oob-swap? Or a select: modifier in hx-oob-swap?

I'm good w/ any pull request, just add tests :)

adicco commented 10 months ago

Hey @guettli, I was actually looking into this myself. Have you found anything else in the meantime?

guettli commented 10 months ago

@adicco sorry, I don't recall how I solved this. I know that there was an issue with sending <tr>...</tr> out-of-band.

But that was solved by carlson: https://github.com/bigskysoftware/htmx/issues/469

Maybe you get a better answer if you ask in the discord channel or at Stackoverflow.

adicco commented 10 months ago

Thanks for the quick reply @guettli

In my case I am using a Bun/Elysia stack with JSX templating, and it would be neat to be able to do something like

<div hx-swap-oob="outerHTML:#my-target-component" hx-swap-oob-source="innerHTML">
<MyComponent />
</div>

Because presently the <div> itself replaces the target's outerHTML. Of course I can get by by doing:

<MyComponent hx-swap-oob="..." />

But it would be neat to separate this concerns and not have components define optional swap properties, and be unaware of whether they would be swapped or not.

@1cg have you come across similar use cases over the years?

Another option would be to have an hx-select-oob on the element issuing the HTMX call, but I kind of liked not having that defined there; it felt that concerns were better separated in this way.

guettli commented 10 months ago

@adicco I would ask at Stackoverflow or at Reddit.

adicco commented 10 months ago

Thanks, I think the multi-swap extension might be what I'm looking for.

guettli commented 10 months ago

Great, then I will close the issue. Feel free to re-open if there is a good reason.

adicco commented 10 months ago

@guettli Actually, I realised that the multi-swap extension wasn't really serving my use case. I simply would like the swapped element to be the first child of the node which has the hx-swap-oob attribute. I believe that this helps those running a JS backend with JSX templating (a la BETH) separate their logical components without them worrying about whether they are to be swapped oob or not. Then we can just wrap these components in a reponse like:

<div hx-swap-oob="outerHTML:#target" hx-swap-oob-source="firstChild">
<MyComponent />
</div>

Instead of having MyComponent handle potential hx-swap-oob arguments (especially with TypeScript shenanigans etc.)

I know this is not in line with the contributions' guidelines, but the changes are so minimal that I went ahead and made a PR

I'd be grateful if you could have a look, and this isn't something you'd want implementend in htmx's core, I'd be glad to hear how I could get around doing that some other way.

I thought of using an extension, as the isInlineSwap function is called, but the issue is that it is not given the oob element itself - only the style and target - so my extension would not be able to know if the swapped element is oob or not. If the node itself was given, I'd be able to check in an extension whether that node has the hx-swap-oob-source attribute or not.

guettli commented 10 months ago

@adicco sound reasonable. But I am the wrong person to talk to.