htmx icon indicating copy to clipboard operation
htmx copied to clipboard

`hx-disabled-elt` on already disabled element

Open StabbarN opened this issue 3 months ago • 2 comments

hx-disabled-elt won't keep the disabled attribute after server has responded. It's problematic when the attribute hasn't been swapped.

Failing test:

  it('preserves pre-disabled elements with hx-disabled-elt on other element', function() {
    this.server.respondWith('GET', '/test', 'ok')
    const btn = make('<button id="b" hx-get="/test" hx-disabled-elt="#a1">Click Me!</button>')
    const a1 = make('<a disabled id="a1"></a>')
    a1.hasAttribute('disabled').should.equal(true)
    btn.click()
    a1.hasAttribute('disabled').should.equal(true)
    this.server.respond()
    a1.hasAttribute('disabled').should.equal(true) // Fails. The `disabled` attribute has been removed.
  })

Copy the test into test/attributes/hx-disabled-elt.js.

A workaround for now is to add :not(:disabled) to hx-disabled-elt's selector.

StabbarN avatar Sep 21 '25 12:09 StabbarN

Yeah currently it is designed to add and then remove the disabled elt from the target. But it looks like it has not been designed to be used on elements that are already disabled. Why would you need to disable an element if it is already disabled is the obvious question to ask? The intended use is for elements that are enabled that need to be disabled just for the duration of the request so they can not be activated accidently during the request. And as you have found in the rare edge case that you have something outside of htmx dynamically disabling things it should be possible to work around this limitation by either using advanced css selectors or by implementing the disable elt function yourself with a little manual JS on and htmx event listener.

MichaelWest22 avatar Sep 21 '25 23:09 MichaelWest22

Why would you need to disable an element if it is already disabled is the obvious question to ask?

I don't, but it's easy to forget to add :not(:disabled). I used hx-disabled-elt on all buttons and the already disabled ones slid along.

A side behaviour of hx-disabled-elt is that the already disabled elements will also become non-disabled after the request. IMO we need to clarify that.

Two suggestions:

  1. Add a note to the documentation of hx-disabled-elt that says something like Pre-disabled elements will not continue to be disabled after request finish.

  2. Exclude all elements that already are disabled. As you said, why would you want to apply hx-disabled-elt on an already disabled element?

StabbarN avatar Sep 22 '25 13:09 StabbarN