Updating the value of an elements hx-trigger does not change its behaviour

102 Views Asked by At

I'm updating the hx-trigger attribute of #refreshToggle to change how often it requests my alert endpoint with the selected value of #timeDropdown using hyperscript. The attribute gets changed correctly but #refreshToggle still uses its starting value of 5s.

It seems like htmx parses and sets all triggers only on page load, because even if I remove the hx-trigger attribute it still runs its trigger, both onclick and every 5s. Is there any way to force a reload/re-parse of triggers?

<div class="container">
  <label for="timeDropdown" class="has-text-white-ter">Refresh every:</label>
  <select name="timeDropdown" id="timeDropdown"
  _="on change set #refreshToggle[@hx-trigger] to `click[this.checked], every ${my value}s[this.checked]`">
    <option value="5">5s</option>
    <option value="10">10s</option>
    <option value="15">15s</option>
    <option value="30">30s</option>
    <option value="60">60s</option>
    <option value="120">2m</option>
    <option value="300">5m</option>
  </select>
</div>
<div class="container">
  <label class="has-text-white-ter"  for="refreshToggle">Toggle automatic polling</label>
  <input class="is-rounded" id="refreshToggle" type="checkbox"
         hx-get="{{ url_for("alerts") }}"
         hx-trigger="click[this.checked], every 5s[this.checked]"
         hx-target="#alert-list"/>
</div>

<div id="alert-list" class="container"></div>
2

There are 2 best solutions below

0
HighestPie On BEST ANSWER

@Ermi pointed me in the right direction. There is a way force a re-parse of the triggers on an element with htmx.process(). I added it to the end of my hyperscript and now it works as intended.

<div class="container">
    <label for="timeDropdown" class="has-text-white-ter">Refresh every:</label>
    <select name="timeDropdown" id="timeDropdown"
      _="on change set #refreshToggle[@hx-trigger] to `click[this.checked], every ${my value}s[this.checked]`
         then call htmx.process(#refreshToggle)">
      <option value="5">5s</option>
      <option value="10">10s</option>
      <option value="15">15s</option>
      <option value="30">30s</option>
      <option value="60">60s</option>
      <option value="120">2m</option>
      <option value="300">5m</option>
    </select>
</div>
1
Ermi On

To force htmx to re-parse the triggers, you can use the htmx.process() function after updating the attribute dynamically.

<div class="container">
  <label for="timeDropdown" class="has-text-white-ter">Refresh every:</label>
  <select name="timeDropdown" id="timeDropdown"
  _="on change set #refreshToggle[@hx-trigger] to `click[this.checked], every ${this.value}s[this.checked]`">
    <option value="5">5s</option>
    <option value="10">10s</option>
    <option value="15">15s</option>
    <option value="30">30s</option>
    <option value="60">60s</option>
    <option value="120">2m</option>
    <option value="300">5m</option>
  </select>
</div>
<div class="container">
  <label class="has-text-white-ter"  for="refreshToggle">Toggle automatic polling</label>
  <input class="is-rounded" id="refreshToggle" type="checkbox"
         hx-get="{{ url_for("alerts") }}"
         hx-trigger="click[this.checked], every 5s[this.checked]"
         hx-target="#alert-list"/>
</div>

<div id="alert-list" class="container"></div>

<script>
document.getElementById('timeDropdown').addEventListener('change', function() {
    // Update the hx-trigger attribute of #refreshToggle based on the selected value of #timeDropdown
    htmx.process(this);
});
</script>

Now, the htmx.trigger() function is called to force htmx to re-parse triggers, making sure that the updated behavior is applied to #refreshToggle.