bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
38.19k stars 1.3k forks source link

On hx-post in the form tag, even when the server retrieves a HX-trigger event the client does not react #2334

Open vitordeoliveira opened 8 months ago

vitordeoliveira commented 8 months ago

On the following code, the idea was after the request, the server dispatched an event to refresh the list of todos, but didn't work.... it works file with hx-delete event, but with hx-post in the form nothing happens, is that a bug? or is intentional?

            <form class="flex mt-4" hx-post="/todolist">
                <input class="shadow appearance-none border rounded w-full py-2 px-3 mr-4 text-grey-600" id="todo" name="todo" type="text" placeholder="Add Todo">
                <button class="flex-no-shrink p-2 border-2 rounded text-teal-600 border-teal-600 hover:text-white hover:bg-teal-600" id="button" type="submit" >Add</button>
            </form>
Telroshan commented 8 months ago

Hey, I'm not sure to understand what is going on here. Clearing the code from the classes that make it less readable gives the following:

<form hx-post="/todolist">
    <input id="todo" name="todo" type="text" placeholder="Add Todo">
    <button id="button" type="submit" >Add</button>
</form>

I don't see where the HX-Trigger you specify in this issue's title is supposed to happen? The only thing I see here is the hx-post of the form, which means it'll make a POST request to the /todolist endpoint on submit (note that it happens on submit because you didn't specify hx-trigger, so htmx uses the fallback / default of submit event on a form)

To make use the HX-Trigger header, you would have another element that would need to be updated, triggered from the server's response, something like

<div hx-get="/whatever" hx-trigger="my-trigger from:body">...</div>

In this case, setting a HX-Trigger to my-trigger from your server response (response to the form's /todolist POST request, would trigger that GET request)

Hope that helps, and if not, please provide more information on your situation so we can figure things out!

H4rryK4ne commented 5 months ago

I am currently struggeling with the same problem.

I have form

<div id="detail">
<form hx-post="/todolist" hx-target="#detail" hx-swap="innerHTML">
    <input id="todo" name="todo" type="text" placeholder="Add Todo">
    <button id="button" type="submit" >Add</button>
</form>
</div>

and another element

<div id="list" hx-get="/whatever" hx-trigger="my-trigger from:body">...</div>

The post request responses with the header HX-Trigger: {"my-trigger": {}"}. But it seems not to trigger the event.

Right after the POST request the form will be replaced by a redirect to the created object detail. However the response of this GET request does trigger an event.

Telroshan commented 5 months ago

Right after the POST request the form will be replaced by a redirect to the created object detail.

Is the POST request being redirected? If so, I think the headers you set won't be even caught by htmx at all as the request will natively follow the redirection. So if I understand correctly that you're making the POST request -> setting the HX-Trigger header -> redirecting the request to another endpoint, then htmx won't even see this HX-Trigger header and only see this redirected endpoint's response headers. In which case, you'll want to set the trigger header from that second endpoint instead of the first.

If not, could you maybe provide more details, i.e. the snippet of your server code that sets the header, or a screenshot of the response in your browser's network tab to confirm the header is indeed in there? Let me know!

H4rryK4ne commented 5 months ago

Is the POST request being redirected? If so, I think the headers you set won't be even caught by htmx at all as the request will natively follow the redirection.

Hmm ... that would be sad ...

you'll want to set the trigger header from that second endpoint instead of the first.

I could do this, but then the event is always triggered when I display the data (e.g. I click on an item in the list, which I want to update with the event) and not only when I create or update the data with the form/POST ...

To prevent this, I would need the information, that this is a redirect from update or create ... but currently I don't have an idea how to do this.

For me this issue is clarified ... thanks for the quick response!