htmx
htmx copied to clipboard
multi-swap extension cannot find element
Error
multi-swap.js:37 HTMX multi-swap: selector '#world' not found in source content.
Code
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/htmx.org"></script>
<script src="https://unpkg.com/htmx.org/dist/ext/multi-swap.js"></script>
</head>
<body hx-ext="multi-swap">
<button hx-get="/api/world" hx-swap="multi:#world">press me</button>
<div id="world"></div>
</body>
</html>
Affects the two browsers I tried, Chrome and Brave: Chrome:Version 120.0.6099.224 (Official Build) (64-bit) Brave: Version 1.61.120 Chromium: 120.0.6099.234 (Official Build) (64-bit)
Same for me, any news about this?
temporary fix for me was to modify the js as following : `(function () {
/** @type {import("../htmx").HtmxInternalApi} */
var api;
htmx.defineExtension('multi-swap', {
init: function (apiRef) {
api = apiRef;
},
isInlineSwap: function (swapStyle) {
return swapStyle.indexOf('multi:') === 0;
},
handleSwap: function (swapStyle, target, fragment, settleInfo) {
if (swapStyle.indexOf('multi:') === 0) {
var selectorToSwapStyle = {};
var elements = swapStyle.replace(/^multi\s*:\s*/, '').split(/\s*,\s*/);
elements.map(function (element) {
var split = element.split(/\s*:\s*/);
var elementSelector = split[0];
var elementSwapStyle = typeof (split[1]) !== "undefined" ? split[1] : "innerHTML";
if (elementSelector.charAt(0) !== '#') {
console.error("HTMX multi-swap: unsupported selector '" + elementSelector + "'. Only ID selectors starting with '#' are supported.");
return;
}
selectorToSwapStyle[elementSelector] = elementSwapStyle;
});
for (var selector in selectorToSwapStyle) {
try {
let el = document.getElementById(selector.slice(1, selector.length))
switch (selectorToSwapStyle[selector]) {
case 'innerHTML':
el.innerHTML = fragment.innerHTML;
break;
case 'outerHTML':
el.outerHTML = fragment.innerHTML;
break;
case 'afterbegin':
el.innerHTML = fragment.innerHTML + el.innerHTML;
break
case 'beforeend':
el.innerHTML += fragment.innerHTML;
break
// Add your case and replacement logic here
}
} catch (err) {
console.warn(err)
}
}
return true;
}
}
});
})();`
This is far from optimal or even the correct way to use the lib, but I it needed to work
It is working fine for me. I ran into this issue before. I fixed it by returning HTML contains the same id. Hence, the return of <button hx-get="/api/world" hx-swap="multi:#world:outerHTML">press me</button>
should contain the element with id "world". For example, the endpoint /api/world
should return<div id="world">Hello World</div>
.