bigskysoftware / htmx

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

hx-swap="outerHTML" breaks hx-trigger="from:...." #375

Open srkunze opened 3 years ago

srkunze commented 3 years ago

Setup

Let's consider the HTML template

<div hx-trigger="load, htmx:afterSwap from:.create_form" hx-target="this" hx-get="{{ view.list_url }}"></div>

<div class="create_form" hx-trigger="load" hx-target="this" hx-get="{{ view.create_url }}" hx-swap="outerHTML"></div>

Problem

As a result, div.create_form is replaced by form.create_form as it should. But when submitting the form, HTMX does not trigger the reloading of the list-div.

srkunze commented 3 years ago

My current workaround is to remove hx-swap="outerHTML" from the div.create_form; resulting in two DOM objects with .create_form.

BoPeng commented 3 years ago

Do not quite understand your set up, but in general I avoid using outerHTML and only replace the content of the elements (e.g. form hx-post) with the content returned by hx-get.

bencroker commented 3 years ago

I suspect this may have to do with the settle delay. Can you try using the htmx:afterSettle event instead of htmx:afterSwap?

srkunze commented 3 years ago

@bencroker

I suspect this may have to do with the settle delay. Can you try using the htmx:afterSettle event instead of htmx:afterSwap?

Alright. I recreated the reproducible state, then tried your suggestion. Unfortunately, the result is the same. The first div is not reloaded after a successful redirect-after post of the form.

srkunze commented 3 years ago

@BoPeng

Do not quite understand your set up

It's the same setup from #362 - a common pattern: a list + a create form on the same page (somehow linked via data dependencies).

in general I avoid using outerHTML

Regarding the issue here, it seems like your advice makes sense, ...

only replace the content of the elements (e.g. form hx-post) with the content returned by hx-get

..., still, this breaks up the create-form into two parts (<form> and <inputs>). Because forms bear additional attributes and behavior attached to it, this makes maintaining them (also potentially on multiple pages) quite difficult.

matiboy commented 10 months ago

Hi @srkunze

This is an old issue but in the hope of seeing it resolved, what do you think of the solution in this repro codepen

It's basically what BoPeng was suggesting but hopefully also fixes your concern about the <form> not being "split" on the backend; basically you keep the container and load the whole form into it. That loading is from innerHTML+load+GET from container, and then later from outerHTML+submit+POST on the form

You can see that the form is the same in both GET and POST responses so this would work just nice with something like a Django FormView and the like.

Glad to hear your thoughts