htmx
htmx copied to clipboard
Cannot scroll on swap with server-sent events
From what I can tell, it's not possible to add any scrolling on swap with server-sent events. I'd like to be able to say hx-swap="beforeend scroll:bottom" and have it just work, but looking at the source code:
function processSSESwap(elt, sseEventName) {
var sseSourceElt = getClosestMatch(elt, hasEventSource);
if (sseSourceElt) {
var sseEventSource = getInternalData(sseSourceElt).sseEventSource;
var sseListener = function (event) {
if (maybeCloseSSESource(sseSourceElt)) {
sseEventSource.removeEventListener(sseEventName, sseListener);
return;
}
///////////////////////////
// TODO: merge this code with AJAX and WebSockets code in the future.
var response = event.data;
withExtensions(elt, function(extension){
response = extension.transformResponse(response, null, elt);
});
var swapSpec = getSwapSpecification(elt)
var target = getTarget(elt)
var settleInfo = makeSettleInfo(elt);
selectAndSwap(swapSpec.swapStyle, elt, target, response, settleInfo)
settleImmediately(settleInfo.tasks)
triggerEvent(elt, "htmx:sseMessage", event)
};
getInternalData(elt).sseListener = sseListener;
sseEventSource.addEventListener(sseEventName, sseListener);
} else {
triggerErrorEvent(elt, "htmx:noSSESourceError");
}
}
I notice that while the swapSpec is parsed correctly, we only ever use swapSpec.swapStyle - completely ignoring swapSpec.scroll.
I think I can probably hack around this for now using the (undocumented) htmx:sseMessage event and adding some JavaScript to scroll to the bottom.
Edit: My workaround is:
<div @htmx:sse-message.camel="$el.scrollIntoView(false)">
Yes. Agreed. Without duplicating a whole lot of code, this would require that html publish a workable swap() method for external scripts to use. So this depends on #255
Another workaround that does not require AlpineJS is this:
<div id="progress-log"
class="mt-4 p-2 h-96 font-mono bg-gray-700 text-gray-100 overflow-y-auto"
hx-swap="beforeend"
sse-swap="message"
hx-on::after-settle="this.scrollTo(0, this.scrollHeight);">
hate to plus one.... but plus one
This also affects the WebSocket extension (basically anything that depends on hx-swap-oob)
https://github.com/bigskysoftware/htmx/issues/2308
And it also affects use of the idiomorph extension with WebSockets:
https://github.com/bigskysoftware/idiomorph/issues/40