htmx icon indicating copy to clipboard operation
htmx copied to clipboard

When using hx-disabled-elt, hx-request is not removed after the request ends

Open flaviocopes opened this issue 1 year ago • 1 comments

As reported in Discord, after adding hx-disable-elt to a button, the hx-request class is never removed from the element after the network request is done.

I made a codepen, basically 'loading...' stays there after the request because of this.

Codepen htmx 1: https://codepen.io/flaviocopes/pen/YzgewLM

Codepen htmx 2: https://codepen.io/flaviocopes/pen/rNRJxod

Temp fix is adding

hx-on::after-request="this.classList.remove('htmx-request')"

flaviocopes avatar Feb 09 '24 09:02 flaviocopes

function removeRequestIndicators(indicators, disabled) {
    forEach(indicators, function (ic) {
        var internalData = getInternalData(ic);
        internalData.requestCount = (internalData.requestCount || 0) - 1;
        if (internalData.requestCount === 0 || ic.getAttribute("hx-disabled-elt") === 'this') { //htmx.js fix
            ic.classList["remove"].call(ic.classList, htmx.config.requestClass);
        }
    });
    forEach(disabled, function (disabledElement) {
        var internalData = getInternalData(disabledElement);
        internalData.requestCount = (internalData.requestCount || 0) - 1;
        if (internalData.requestCount === 0) {
            disabledElement.removeAttribute('disabled');
        }
    });
}

jay23606 avatar Feb 09 '24 11:02 jay23606

I have the same issue. It happens on both versions 1 and 2.

pauloevpr avatar Jul 03 '24 02:07 pauloevpr

This is what is causing the problem for me.

I have this layout: <form method="POST" hx-disabled-elt="#Save"> <tbody hx-trigger="onload"> <button id="Save" type="submit">Save</button> </form>

This is the order functions are called. initNode(<form>); initNode(<tbody>);

issueAjaxRequest - is called and puts an htmx-internal-data:requestCount = 1 on <button>.

initNode(<button>); Initializing the button removes htmx-internal-data:requestCount = 1.

Line 2789 in htm.js 2.0 evaluates to false: if (nodeData.initHash !== attributeHash(elt)) { deInitNode(elt) <- this removes the requestCount = 1 on the <button> }

issueAjaxRequest xhr.onload - is called, and it tries to remove the disabled attribute on <button> Line 2784 removeRequestIndicators(indicators, disableElts)

That call doesn't remove the disabled attribute because htmx-internal-data:requestCount does not exist.

BTW, if I move <button> above the <tbody> then hx-disabled-elt works correctly for me.

jroberts-ses avatar Jul 03 '24 12:07 jroberts-ses