houndy
houndy

Reputation: 13

Why isn't my nav updating after htmx trigger?

I have a django project with a left navbar list of projects. I am new to htmx and I'm using it to update the project list after a new project is created from a form. I can see the htmx trigger event and the payload looks correct and the target div element looks correct. However, the update doesn't occur. I've tried including from:body. I have a hx-target in the form and I generate the HX-Trigger in the view, but I'm not sure if that's correct.

Here is my views.py:

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from apps.projects.models import Project, ProjectUser
from apps.projects.forms import ProjectForm
from apps.teams.models import Team
from apps.users.models import CustomUser
from django.http import JsonResponse
from django.db.models import Q
from django.shortcuts import render, get_object_or_404, HttpResponse
from .utils import is_htmx_request
from django.template.loader import render_to_string

import logging

# Configure logging
logger = logging.getLogger(__name__)

@login_required
def project_create(request, team_slug):
    print(f'made it in creaTE')
    team = Team.objects.get(slug=team_slug)
    form = ProjectForm(team=team)

    if request.method == "POST":
        form = ProjectForm(request.POST, team=team)
        if form.is_valid():
            print(f'form: {form}')
            project = form.save(commit=False)
            project.team = team
            project.save()  # Save the project to get a project_id

            members_ids = request.POST.getlist("members")
            add_from_projects_ids = request.POST.getlist("add_from_projects")

            # Add current user to the project if visibility is "members"
            if project.visibility == "members":
                ProjectUser.objects.create(project=project, user=request.user)

            # Add all team members to the project if visibility is "team"
            if project.visibility == "team":
                for member in team.members.all():
                    ProjectUser.objects.create(project=project, user=member)

            # Add selected members to the project
            for member_id in members_ids:
                member = CustomUser.objects.get(id=member_id)
                ProjectUser.objects.create(project=project, user=member)

            # Add members from selected projects to the new project
            for project_id in add_from_projects_ids:
                other_project = Project.objects.get(project_id=project_id)
                for user in other_project.user_associations.all():
                    if not ProjectUser.objects.filter(project=project, user=user).exists():
                        ProjectUser.objects.create(project=project, user=user)
            
            # Get updated project list
            projects = Project.objects.filter(team=team)

            # Render project list HTML
            project_list_html = render_to_string('projects/project_list.html', {'projects': projects})
            print(f'proj html: {project_list_html}')
            # Prepare HTMX response
            response = HttpResponse(project_list_html)
            response['HX-Trigger'] = 'refreshProjectList'
            print(f'response content: {response.content.decode("utf-8")}')  # Print the response content
            # Log the headers to verify 'HX-Trigger'
            for header, value in response.items():
                print(f'Header: {header}, Value: {value}')

            return response

    return render(request, "projects/project_form.html", {"form": form, "team_slug": team_slug})

@login_required
def get_project_list(request, team_slug):
    print("get_project_list")
    team = get_object_or_404(Team, slug=team_slug)
    projects = Project.objects.filter(team=team)
    print(projects)
    return render(request, "projects/project_list.html", {"projects": projects})

And here is my form:

{% load i18n %}
<div class="card mt-3">
    <div class="card-header">
        <h5>{% translate "Create Project" %}</h5>
        <button type="button" class="close" aria-label="Close"
            onclick="document.getElementById('project-form-container').innerHTML = '';">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
    <div class="card-body">
        <form id="create-project-form" method="post" hx-post="{% url 'projects:project_create' team_slug %}"
            hx-target="#project-list2" hx-swap="innerHTML">
            {% csrf_token %}
            {{ form.as_p }}
            <div>
                <label for="id_entities_search">{% translate "Search Team Members or Projects:" %}</label>
                <input type="text" id="id_entities_search" class="form-control"
                       placeholder="{% translate 'Start typing to search...' %}">
                <ul id="entities_results" class="list-group"></ul>
                <div id="selected_entities"></div>
            </div>
            <button type="submit" class="pg-button-primary">{% translate "Create Project" %}</button>
        </form>
    </div>
</div>

And here is my team_nav.html:

{% load i18n %}
{% load team_tags %}
<div class="mt-2">
  <a class="pg-button-secondary" hx-get="{% url 'projects:project_create' request.team.slug %}"
    hx-target="#project-form-container" hx-swap="innerHTML">
    <span class="pg-icon"><i class="fa fa-plus"></i></span>
    <span>{% translate "Add Project" %}</span>
  </a>
</div>


<div id="project-list2" hx-target="this" hx-trigger="refreshProjectList from:body" hx-swap="innerHTML">
  {% include 'projects/project_list.html' %}
</div>


And here is the project_list.html:

{% load i18n %}
<h3 class="text-2xl py-4">{% translate "Projects" %}</h3>
<ul class="list-group">
  {% for project in projects %}
  <li class="list-group-item">
    <a href="{% url 'projects:project_detail' project.project_id %}">{{ project.title }}</a>
  </li>
  {% empty %}
  <li class="list-group-item">{% translate "No projects found." %}</li>
  {% endfor %}
</ul>

I have tried changing the hx-swap and I can see the htmx event trigger using a js alert on the base.html. And I can see that the html preview looks correct. The project is being created, but the navbar doesn't update.

Upvotes: 0

Views: 111

Answers (1)

Imesh Isuranga
Imesh Isuranga

Reputation: 39

Insert below to form tag.

hx-push-url = "true"

Also, there may be a browser cache issue. I am also faced with this issue. After manually refreshing my browser I could see my unloaded components. Then I used the below code in base.html.

<script>

    document.addEventListener('htmx:afterRequest', function(evt) {
        location.reload();
    });

</script>

Upvotes: 0

Related Questions