womblerone
womblerone

Reputation: 532

htmx:afterSettle not working with hx-trigger

This code does not trigger a swap event, even though I can see that the afterSettle event is firing in the console.

<div id="product-gallery" hx-trigger="htmx:afterSettle" hx-get="{% url 'products' %}" hx-swap="outerHTML">

This works, but loops forever of course, with:

<div id="product-gallery" hx-trigger="load" hx-get="{% url 'products' %}" hx-swap="outerHTML">

I can see from htmx.logAll() that the htmx:afterSettle even is firing, it's just not triggering the above element. Have also tried htmx:afterSwap, which is also logged by logAll()

I'm trying to reload the gallery after a form has been swapped out (the form is inside this parent product-gallery div). Which I was hoping I could achieve by adding a from constraint:

<div id="product-gallery" hx-get="{% url 'products' %}" hx-swap="outerHTML" hx-trigger="afterSettle from:.product-form">

Structure is:

<div id="product-gallery">
<div id="product-form-1"> 
<form>
...
</form>
</div>
...
</div>

Update - it works! Followed solution 3 from https://htmx.org/examples/update-other-content/: I added a header to my response in the form update view:

if form.is_valid():
    form.save()
    context = dict()
    context['form'] = form
    response = render(self.request, 'form_product.html', context)
    response['HX-Trigger'] = 'productUpdate'
    return response

Then I listen for this event in the gallery div:

<div id="product-gallery" hx-get="{% url 'products' %}" hx-swap="outerHTML" hx-trigger="productUpdate from:body">

The one bit of js I retain is for closing forms when they are valid:

htmx.on("htmx:afterSwap", function(evt) {
    const eventIdTarget = evt['target'].id;
    if (eventIdTarget === 'product-gallery') {
        if ($("[id^=product-form] .alert-warning").length === 0) {
            $.magnificPopup.close();
        }
    }
})

Upvotes: 1

Views: 6861

Answers (2)

guettli
guettli

Reputation: 27089

AFAIK you can't use "afterSettle" like this: hx-trigger="htmx:afterSettle".

If you want to update a second part of the page, then you can use OOB (out-off-band):

The hx-swap-oob attribute allows you to specify that some content in a response should be swapped into the DOM somewhere other than the target, that is "Out of Band". This allows you to piggy back updates to other element updates on a response.

https://htmx.org/attributes/hx-swap-oob/

More about Update other content

Upvotes: 1

guettli
guettli

Reputation: 27089

If you have troubles with http redirects, then this might help you:

If you want a response which was triggered via htmx to do a full page reload, then you should not return a http redirect response (302, aka as HttpResponseRedirect in Django).

You need to set the hx-redirect response header: https://htmx.org/reference/#response_headers

If you set hx-redirect and set the http response code to 302, then htmx will do a redirect on ajax-level (not on the full screen).

Next thing which might confuse new users: if you are used to the old post/redirect/get pattern, then there are good news: This is not needed any more.

If the client sends a http-post, and all data validates, you should return a http 2xx response containing the new HTML. There is no need for the outdated redirect/get dance.

If you think the htmx docs could get improved, then you might want to create a pull request to improve the docs.

Upvotes: 2

Related Questions