htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Cannot scroll on swap with server-sent events

Open ocharles opened this issue 3 years ago • 5 comments

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.

ocharles avatar Jan 27 '22 16:01 ocharles

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)">

ocharles avatar Jan 27 '22 16:01 ocharles

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

benpate avatar May 14 '22 21:05 benpate

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);">

wimdeblauwe avatar Oct 08 '23 08:10 wimdeblauwe

hate to plus one.... but plus one

danawoodman avatar Jan 25 '24 05:01 danawoodman

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

aral avatar Feb 22 '24 12:02 aral