Search code examples
javascriptpythondjangohtmxintercooler.js

Using multiple custom event as triggers in HTMX, can I identify which of the triggers is being used?


I am using HTMX in my Django project to change elements in a form depending on previous selections. At some point I use a custom event and listen for it as indicated in solution 3 here: https://htmx.org/examples/update-other-content/

Everything works as expected, also when using two triggers separated by a comma.

However, I would like to pass a header, the value of which depends on the event being used as trigger. Trigger foo -> header A, trigger bar -> header B. Below is some code that should help understand.

<div hx-get="{% url 'someurl' %}" 
     hx-trigger="foo from:body, bar from:body" 
     hx-target="#sometarget"
     hx-swap="outerHTML"
     hx-headers='{"someheader":"foo_value"}' OR '{"someheader":"bar_value"}'>

So far, I have tried:

  • putting target.value as header value (you can use it as trigger filter, so I thought it might work in hx-headers too)
  • Passing headers or context variables in the view that causes the trigger to go off, so that then I can use Django's {% if %} in the template. But they don't get here because that view renders a different part of the template, and this is just being triggered because it listens for the event on the body due to event bubbling

Any suggestions?


Solution

  • HTMX provides the htmx:configRequest event, where we can inspect and alter the payload before HTMX dispatches the request. The triggering event is located in the evt.detail.triggeringEvent.type property, the header object is at evt.detail.headers. So we can add a custom header depending on the triggering event by including the following JS snippet on the specific page:

    <script>
    document.body.addEventListener('htmx:configRequest', (evt) => {
      if (evt.detail.triggeringEvent.type === 'foo') {
        evt.detail.headers['someheader'] = 'foo_value'
      }
      if (evt.detail.triggeringEvent.type === 'bar') {
        evt.detail.headers['someheader'] = 'bar_value'
      }
    })
    </script>