Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/htmx.js
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,11 @@ var htmx = (function() {
fragment = getDocument().createDocumentFragment()
fragment.appendChild(oobElementClone)
if (!isInlineSwap(swapStyle, target)) {
fragment = asParentNode(oobElementClone) // if this is not an inline swap, we use the content of the node, not the node itself
// @ts-ignore if elt is template content will be valid so use as inner content
fragment = oobElementClone.content || asParentNode(oobElementClone) // if this is not an inline swap, we use the content of the node, not the node itself
}
if (swapStyle === 'outerHTMLStrip') {
swapStyle = 'outerHTML' // outerHTMLStrip will strip wrapping tag above but do outerHTML swap of inner contents
}

const beforeSwapDetails = { shouldSwap: true, target, fragment }
Expand Down
20 changes: 20 additions & 0 deletions test/attributes/hx-swap-oob.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ describe('hx-swap-oob attribute', function() {
byId('d1').innerHTML.should.equal('Swapped5')
})

it('handles outerHTMLStrip response properly', function() {
this.server.respondWith('GET', '/test', "Clicked<div id='d1' hx-swap-oob='outerHTMLStrip'><div id='d2' foo='bar'>Swapped4.1</div></div>")
var div = make('<div hx-get="/test">click me</div>')
make('<div id="d1"></div>')
div.click()
this.server.respond()
byId('d2').getAttribute('foo').should.equal('bar')
div.innerHTML.should.equal('Clicked')
byId('d2').innerHTML.should.equal('Swapped4.1')
})

it('oob swaps can be nested in content with config {"allowNestedOobSwaps": true}', function() {
htmx.config.allowNestedOobSwaps = true
this.server.respondWith('GET', '/test', "<div>Clicked<div id='d1' foo='bar' hx-swap-oob='innerHTML'>Swapped6</div></div>")
Expand Down Expand Up @@ -387,4 +398,13 @@ describe('hx-swap-oob attribute', function() {
element.innerHTML.should.equal('Swapped11')
})
})

it('handles using template as the encapsulating tag of an inner swap', function() {
this.server.respondWith('GET', '/test', '<tbody id="foo" hx-swap-oob="innerHTML"><tr><td>Swapped12</td></tr></tbody>')
var div = make('<div hx-get="/test">click me</div>')
make('<table><tbody id="foo"></tbody></table>')
div.click()
this.server.respond()
byId('foo').innerHTML.should.equal('<tr><td>Swapped12</td></tr>')
})
})
23 changes: 22 additions & 1 deletion www/content/attributes/hx-swap-oob.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The value of the `hx-swap-oob` can be:

If the value is `true` or `outerHTML` (which are equivalent) the element will be swapped inline.

If a swap value is given, that swap strategy will be used and the encapsulating tag pair will be stripped for all strategies other than `outerHTML`.
If a swap value is given, that swap strategy will be used and the encapsulating tag pair will be stripped for all strategies other than `outerHTML`. There is also an additional swap value `outerHTMLStrip` that still strips the encapsulating tag but allows the replacment the whole target, like `outerHTML`, with all inner content nodes.

If a selector is given, all elements matched by that selector will be swapped. If not, the element with an ID matching the new content will be swapped.

Expand Down Expand Up @@ -71,6 +71,27 @@ A `<p>` can be encapsulated in `<div>` or `<span>`:
</span>
```

You can also now use `template` tag as this should work for nearly any tag type:
```html
<template hx-swap-oob="beforeend:#table tbody">
<tr>
...
</tr>
</template>
```

Another new option is the `outerHTMLStrip` swap style that allows you to replace an element with multiple nodes:
```html
<div id="foo" hx-swap-oob="outerHTMLStrip">
<div id="foo2">
Replace original
</div>
<div>
And add something more
</div>
</div>
```

### Troublesome Tables and lists

Note that you can use a `template` tag to encapsulate types of elements that, by the HTML spec, can't stand on their own in the
Expand Down