htmx
htmx copied to clipboard
changed + from in hx-trigger
Using changed along from in hx-trigger seems to have an unexpected behaviour.
Given the following code (you can also play it in this JSFiddle):
<form hx-get="/search" hx-target="#result" hx-trigger="keyup changed delay:250ms from:#searchInput, change">
<label>Search <input id="searchInput" class="flex-grow" type="search" name="search"></label>
<label>Category <select name="category">
<option value="A">A</option>
<option value="B" selected>B</option>
<option value="C">C</option>
</select>
</label>
</form>
You can see here how the request isn't triggered when typing in the input, only when the change event is fired (which happens in my case, when focusing out the input)
it seems, that changed is checked for the form itself, not for the element that triggered the request using the from modifier.
I would naively expect htmx to check if the value changed, for the element that triggered the event, not on the element that declares hx-trigger.
A convoluted example I'll admit, but just to showcase the issue more clearly, on this JSFiddle
<label>Defines Hx-trigger <input type="text" hx-get="/search" hx-trigger="keyup changed delay:250ms from:#searchInput" hx-target="#result" hx-include="#searchInput"></label>
<label>Type in to search <input id="searchInput" type="search" name="search"></label>
You can see here how, typing in the second input, has no effect, unless you modified the value of the first input first.
Such a setup (the first one, not the second one which directly comes from hell) seems common to me as it basically comes down to factoring the hx-get/trigger/swap on a single root element, and having multiple children trigger it differently without specifying hx-get/trigger/swap on every single one of them.
long standing issue, thank you for working on it!
Using input and change together worked for me:
<form hx-get="{% url 'index' %}"
hx-target="#product_list"
hx-trigger="input change">
<input type="text" name="search" id="search">
<select name="category" id="category">
<option value="">All</option>
{% for category in categories %}<option value="{{ category.id }}">{{ category.name }}</option>{% endfor %}
</select>
</form>