diff --git a/src/htmx.js b/src/htmx.js index bbe83cec9..ed1e33b33 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -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 } diff --git a/test/attributes/hx-swap-oob.js b/test/attributes/hx-swap-oob.js index 875c4d452..c058c58b7 100644 --- a/test/attributes/hx-swap-oob.js +++ b/test/attributes/hx-swap-oob.js @@ -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
Swapped4.1
") + var div = make('
click me
') + make('
') + 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', "
Clicked
Swapped6
") @@ -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', 'Swapped12') + var div = make('
click me
') + make('
') + div.click() + this.server.respond() + byId('foo').innerHTML.should.equal('Swapped12') + }) }) diff --git a/www/content/attributes/hx-swap-oob.md b/www/content/attributes/hx-swap-oob.md index 94393fb32..b91a40788 100644 --- a/www/content/attributes/hx-swap-oob.md +++ b/www/content/attributes/hx-swap-oob.md @@ -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. @@ -71,6 +71,27 @@ A `

` can be encapsulated in `

` or ``: ``` +You can also now use `template` tag as this should work for nearly any tag type: +```html + +``` + +Another new option is the `outerHTMLStrip` swap style that allows you to replace an element with multiple nodes: +```html +
+
+ Replace original +
+
+ And add something more +
+
+``` + ### 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