So I'm trying to display a feedback message saying "added" or "failed" when a form is submitted with HTMX to my Django backend.
Basically what I have right now is a form that performs an hx-post, and the reply is a div containing the updated information, which is swapped with the current contents of the div.
<div id="list">
<!-- The stuff in here is loaded through another template, which is
the result of a successful myApp:add operation. -->
</div>
<form hx-post="{% url 'myApp:add' eid=e.id %}" hx-swap="outerHTML" hx-target="#list">
<!-- Some stuff in here -->
</form>
<div id="result">
<!-- Here I should print a message saying correct or incorrect
depending on the HTMX result (if the entry was added or there was
any kind of error, even connection errors) -->
</div>
The thing is, in case of an error in the form or in the request itself, the list will remain the same, but I would like for it to print something like "error" in the result div. In case the new entry is added correctly I would like to print a "success" message in the result div.
Note that I can't return the result div as part of the hx-post response DOM since the connection might fail. So the failure message wouldn't be displayed.
I'm also using Alpine.js, if that's any help.
Here's one way to do it using Alpine if you can add a div around the existing code:
<div x-data="{ state: '' }"
@htmx:send-error="state = 'send error'"
@htmx:response-error="state = 'response error'"
@htmx:after-swap="state = 'success'"
>
<div id="list"></div>
<form hx-post="{% url 'myApp:add' eid=e.id %}" hx-swap="outerHTML" hx-target="#list">
<button type="submit">Submit</button>
</form>
<div id="result">
<span x-text="state"></span>
</div>
</div>
The events are triggered on the target #list so they bubble up to the parent div. If you prefer to add the Alpine component to the #result div you can do it by listening for the events on the window:
<div id="result" x-data="{ state: '' }"
@htmx:send-error.window="state = 'send error'"
@htmx:response-error.window="state = 'response error'"
@htmx:after-swap.window="state = 'success'">
<span x-text="state"></span>
</div>
If you use the second approach and you have multiple htmx requests happening on the same page you could also read the $event.detail.target.id value within the Alpine events to add some logic. In the above case the value should be list.
To deal with specific response codes from the server you can check the $event.detail.xhr.status value in events. For example:
<div id="result" x-data="{ state: '' }"
@htmx:send-error.window="state = 'send error'"
@htmx:response-error.window="state = $event.detail.xhr.status == 400 ? 'validation error' : 'response error'"
@htmx:after-swap.window="state = 'success'">
<span x-text="state"></span>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With