htmx
htmx copied to clipboard
oob-swap losing root element
Discussed in https://github.com/bigskysoftware/htmx/discussions/1997
Originally posted by graemetait November 13, 2023
I think I'm misunderstanding something about how oob-swap works. I would expect the following example to insert the <li> to the end of the <ul>, but the surrounding <li> tag is always removed, inserting just the content.
https://codepen.io/graemetait/pen/gOqxMMK?editors=1010
It's also very similar to solution 2 in this example. https://htmx.org/examples/update-other-content/
What am I doing wrong?
Btw, see this JSFiddle, with the doc's own example that doesn't work as expected, making me think it's a bug rather than a documentation issue there:
The tds are added to the tbody directly, and as the OP reports, ignoring the root element (here, a tr), leading to an invalid HTML ; tbody should only contain tr elements
Permitted content | Zero or more
trelements
@graemetait, since you want to swap the entire <li> element, you need to wrap it in a container. The 'swap' option 'beforeend' uses the inner HTML of the element it's specified on, and therefore, it only swaps the innerHTML of the <li>.
Changing the response body to the following will fix your issue.
<div hx-swap-oob="beforeend:#list">
<li>next item</li>
</div>
Thanks for the response, @xhaggi. Wrapping it in an element certainly works, but is that the intent with this feature? The example in the docs for beforeend doesn't add a container element, but actually the example doesn't work correctly if you run it.
The docs only say the following.
beforeend - Insert the response after the last child of the target element
Are we saying that the reality is...
beforeend - Insert the inner html of the response after the last child of the target element
Expanding upon that, the docs do reference that the options are based upon Element.insertAdjacentHTML. If you were to use beforeend with insertAdjacentHTML it wouldn't be using innerHTML and you wouldn't need a container element.
It would be good to get some direction from the owner of this feature if there is one.
Can anyone shed some light on why this works with a
- to add
- items but fails completely with a table when trying to add
to a table? It will append the "row" but completely strip out all and tags making it useless. If it uses Element.insertAdjacentHTMLthen it should work since plain JS can be used to add rows to a table that way.
@Beartech I had to wrestle with this for a while. The answer is similar to @xhaggi 's, except instead of wrapping your <tr> with a <div>, wrap it with a <tbody> instead.
https://github.com/bigskysoftware/htmx/issues/1198#issuecomment-2100852239