Search code examples
javascripthtmxhyperscript

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


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>

Solution

  • @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>