htmx icon indicating copy to clipboard operation
htmx copied to clipboard

hx-disabled-elts doesn't work in conjunction with hx-indicator

Open jy14898 opened this issue 2 years ago • 2 comments

They share the same internal counter, which means that having both on the same element will count to 2 when triggering the request, but when the request completes it first tries to remove request indicators, and then removes disableds.

This is a problem, as when performing the remove indicators step, the counter is decremented 2 -> 1, but it must be 0 for the indicator to be removed.

https://github.com/bigskysoftware/htmx/blob/c7f9dcb6824b11d2fbb7d465b83546ed07c77de7/src/htmx.js#L2360-L2375 L2365 will never trigger with both.

IMO the easiest solution is separate counters, eg internalData.disabledRequestCount, or updating the documentation that these features are incompatible.

jy14898 avatar Oct 24 '23 19:10 jy14898

Bug confirmed as seen in reproduction codepen

An alternative to adding a separate requestCount would be to rewrite the function to detect elements that are both indicators and disabled, something like below; sadly IE11 compatibility doesn't allow us to simply use Nodelist.contains

function removeRequestIndicators(indicators, disabled) {
    function removeIndicator(el) {
        el.classList["remove"].call(el.classList, htmx.config.requestClass);
    }
    var handled = []
    forEach(indicators, function (ic) {
        handled.push(ic)
        var internalData = getInternalData(ic);
        internalData.requestCount = (internalData.requestCount || 0) - 1;
        if (internalData.requestCount === 0) {
            removeIndicator(ic)
        }
    });
    forEach(disabled, function (disabledElement) {
        
        var internalData = getInternalData(disabledElement);
        internalData.requestCount = (internalData.requestCount || 0) - 1;
        if (internalData.requestCount === 0) {
            disabledElement.removeAttribute('disabled');
            if(handled.indexOf(disabledElement) !== -1) {
                //               See if they were also an indicator
                removeIndicator(disabledElement)
            }
            
        }
    });
    
}

I added this code to the codepen (just need to uncomment it) and it seems to work fine; but tests need to be written and PR created.

matiboy avatar Nov 04 '23 02:11 matiboy