htmx icon indicating copy to clipboard operation
htmx copied to clipboard

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

Open srkunze opened this issue 4 years ago • 6 comments

Setup

Let's consider the HTML template

  • for URL /home/
<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>
  • for URL /create/
<form class="create_form" hx-post="{{ view.create_topic_url }}" hx-target="this" hx-swap="outerHTML">
    ....
</form>

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 avatar Feb 18 '21 09:02 srkunze

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

srkunze avatar Feb 18 '21 09:02 srkunze

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.

BoPeng avatar Feb 19 '21 00:02 BoPeng

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

bencroker avatar Feb 19 '21 12:02 bencroker

@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 avatar Feb 22 '21 15:02 srkunze

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

srkunze avatar Feb 22 '21 15:02 srkunze

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

matiboy avatar Nov 05 '23 02:11 matiboy