hx-vals in combination with multiple triggers does not have the "event" object attached for both?

360 Views Asked by At

It is only attatched to the fist one of the multiple triggers. Here is an example codepen: https://codepen.io/viggiesmalls/pen/NWoRryY

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
    <script>
        function logEvent(evt) {
          console.log(evt)
        }
    </script>
</head>
<body>
<input type="text" hx-post="/hx/validate" hx-vals="js:{value: logEvent(event)}" hx-trigger="keyup,change delay:200ms changed" hx-target="next .errors">
<div class="errors"></div>
</body>
</html>

The exaple above only logs the "event" object on the keyup event, but not on change ( when I click away from the input field) If I swap change and keyup like this:

hx-trigger="change, keyup delay:200ms changed"

then the "event" object is only attatched to the change event, and not the keyup event.

Why is that? What would be the correct way to to specify hx-trigger in order to have the "event" object attached to both, and a delay of 200ms?

2

There are 2 best solutions below

0
On

I think this is htmx issue with evaluating js for hx-vals when using delayed triggers.

More details can be found here: https://github.com/bigskysoftware/htmx/issues/1658

The workaround may be to use debounce inside the evaluated js function fo now, until the case is handled properly in the future versions.

1
On

You pose a really interesting question.

As this answer here and the official docs show, it is possible to chain hx-triggers as a comma-separated list.

You can also chain them with modifiers, such as the below (notice you don't need the changed modifier with the change trigger - that causes issues):

<input type="text" hx-post="/hx/validate" 
  hx-trigger="keyup delay:200ms, change delay:200ms" hx-target="next .errors">

This should fix most of your problem.

But you'll notice I've removed hx-vals from the above code. That's because I think you're listening to 'event' incorrectly here, and misusing hx-vals. hx-vals is a shorthand way to send extra info to the server, primarily as JSON. See below from the docs:

The hx-vals attribute allows you to add to the parameters that will be submitted with an AJAX request. By default, the value of this attribute is a list of name-expression values in JSON (JavaScript Object Notation) format.

If you want to listen to the HTMX event, as per this answer you should do so like this:

document.addEventListener('htmx:afterRequest', function(evt) {
    console.log(evt);
});

So if you put all this together like the below, you should find both triggers successfully work and fire events which you can listen to in the console:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/[email protected]" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
</head>
<body>
<input type="text" hx-post="/hx/validate"
  hx-trigger="keyup delay:200ms changed, change delay:200ms" hx-target="next .errors">
<div class="errors"></div>
<script>
    document.addEventListener('htmx:afterRequest', function(evt) {
        console.log(evt);
    });
</script>
</body>
</html>