Reputation: 13
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">×</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
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