htmx icon indicating copy to clipboard operation
htmx copied to clipboard

hx-trigger="mousedown[button===0]" does not work while "mousebutton[button===1]" does

Open sebsprenger opened this issue 4 months ago • 3 comments

Context I am working with a password field which also has a button to display the password in cleartext. When I press the button the blur event of the input fires and replaces the entire inputfield including the button, so that the click event is never fired. It works with a mousedown event, however it fires on all mousebuttons not only the primary button.

Problem I wanted to use event filters to check if the primary button had been pressed (hx-trigger="mousedown[button===0]"). While it works for secondary (button===2) and middle (button===1) mouse buttons, it does not seem to work for the primary mouse button. I tested on OSX with Chrome, Firefox, and Safari.

Is 0 handled differently in the event filter mechanism? Do I have to apply the expression differently?

Here is an HTMX v2.0.6 example to demonstrate:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
</head>
<body>

<script src="https://unpkg.com/[email protected]"></script>

<script>
    document.addEventListener('mousedown', (e) => {
        console.log('Button: ' + e.button + ' is zero ' + (e.button === 0));
        console.log('Button: ' + e.button + ' is one ' + (e.button === 1));
        console.log('Button: ' + e.button + ' is two ' + (e.button === 2));
        console.log('----------');
    });
</script>

<button hx-trigger="mousedown[button===0]" hx-get="content.html" hx-target="#my-target" hx-swap="innerHTML">
    Primary Button
</button>
<button hx-trigger="mousedown[button===2]" hx-get="content.html" hx-target="#my-target" hx-swap="innerHTML">
    Secondary Button
</button>
<button hx-trigger="mousedown[button===1]" hx-get="content.html" hx-target="#my-target" hx-swap="innerHTML">
    Middle Button
</button>

<div id="my-target">
    <!-- content area -->
</div>

</body>
</html>

content.html

<p>content</p>

sebsprenger avatar Aug 12 '25 18:08 sebsprenger

can you try with mousedown[event.buton===0]

I think what is happening is to make these event filters to work with simple syntax it coverts button === 0 into a more complex string where it checks if event.button exists and if it does uses this otherwise uses window.button so you can reference either event or global scoped variables easily.

the htmx code is:

conditionalSource += '((' + paramName + '.' + token + ') ? (' + paramName + '.' + token + ') : (window.' + token + '))'

But if the variable is falsey like 0 or '' this will fail as it will test window.button === 0 instead which is not ideal. you can also fix this by using button==null but this is less logical. adding an explicit event. instead of letting it try to add it for you is probably better.

ideally htmx could use something like:

conditionalSource += '((' + paramName + '.' + token + ' != null) ? (' + paramName + '.' + token + ') : (window.' + token + '))'

Not sure if this quirky edge case needs a fix or not

MichaelWest22 avatar Aug 13 '25 04:08 MichaelWest22

So it would only work with mousedown[button] if button was a boolean. I tested your suggestion and it works for me! Thanks a ton! I do not yet understand though why it seems works for mousedown[button===1] and mousedown[button===2].

The documentation on https://htmx.org/attributes/hx-trigger/ is not very explicit about it and talks about "enclosing a boolean javascript expression in square brackets". Maybe the fix is to adjust the documentation to highlight that for comparisons we need to use mousedown[event.button===0] instead.

sebsprenger avatar Aug 13 '25 05:08 sebsprenger

On second thought... If I got you right it is about 0 being interpreted as null. Which also makes sense considering that the notation works fine for mousedown[button===1] and mousedown[button===2].

In that case, while it would work to explain the circumstance in the documentation, as a user I do find this very surprising and errorprone. Thus, I would prefer an adjustment in the code :-)

sebsprenger avatar Aug 13 '25 06:08 sebsprenger