Get messages and errors in template by htmx

I have a form on page through which the user can update profile information. Everything works fine, but I decided to make the information update without having to reload the page through a post request using htmx. I changed my form as follows:

<form hx-post="{% url 'dashboard:profile' %}" hx-target="html" hx-swap="outerHTML">
    {% csrf_token %}
    ...
</form>

url:

path('profile/', views.ProfileUpdateView.as_view(), name='profile')

view:

class ProfileUpdateView(View):
    template_name = 'dashboard/profile.html'

    def get(self, request, *args, **kwargs):
        user = request.user
        profile = user.profile
        user_form = forms.UserForm(instance=user)
        profile_form = forms.UserProfileForm(instance=profile)
        context = {'user_form': user_form, 'profile_form': profile_form}
        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):
        user = request.user
        profile = user.profile
        user_form = forms.UserForm(request.POST, instance=user)
        profile_form = forms.UserProfileForm(request.POST, instance=profile)
        context = {'user_form': user_form, 'profile_form': profile_form}
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'success')
        else:
            messages.error(request, 'error')
        return render(request, self.template_name, context)

Everything works correctly, but the messages that I send through messages or the errors that I receive through form validation in the template are not displayed and the page remains unchanged if it receives an error or message.
template:

{% include 'src/alerts.html' with messages=messages %}
<form hx-post="{% url 'dashboard:profile' %}" hx-target="html" hx-swap="outerHTML">
    {% csrf_token %}
    {{ user_form }}
    {{ profile_form }}
    <button type="submit">Submit</button>
</form>

How can I solve this problem?

You cannot replace the entire html element in htmx. At most, you can replace the innerHTML of the “body” element.
(See </> htmx ~ hx-swap Attribute)

I would suggest changing your rendering to render the messages and form as two different divs, with each having the attribute hx-swap-oob="True"
(See </> htmx ~ hx-swap-oob Attribute)

1 Like

I tried to replace the body but some of eventListeners in my js code were broken and not working properly. Like DOMContentLoaded. I tried using htmx:afterSwap instead, but that didn’t work either

I’m sorry, I didn’t mean to imply that you should be replacing body.

You should be replacing only the divs that need to be replaced.

If your form is one div and the messages a different div, then you’d be creating those two divs and sending that as the response.