Rending a separate page dynamically using django and htmx
Am working on a simple task app using Django and HTMX. I want when a user clicks on a button in the navbar to add a task, the add task page should be displayed dynamically without causing a page reload. Yes the task page gets displayed dynamically but when i try to reload my page Some content of the page gets lost. Checkout below the code snippets
navbar.html
{% load static %}
<div class="flex justify-between pt-10 pb-3">
<div class="w-6/12">
<div class="font-bold text-gray-700 text-2xl" style="cursor: pointer;">Task Manager</div>
</div>
<div class="w-1/12 text-gray-500" style="cursor: pointer;">Home</div>
<div class="w-1/12 text-gray-500" style="cursor: pointer;">Pending</div>
<div class="w-1/12 text-gray-500" style="cursor: pointer;">Complete</div>
<div class="w-1/12 text-gray-500" style="cursor: pointer;">Pricing</div>
<div class="w-1/12 text-gray-500">
<div class="flex justify-center items-center">
<a role="button" class="bg-blue-700 rounded text-white font-bold text-sm px-4 py-1" href="{% url "create_todo" %}" hx-get="{% url "create_todo" %}" hx-push-url="true" hx-target="#main">Add Task</a>
</div>
</div>
<div class="w-1/12 text-gray-500">
<div class="flex justify-center items-center">
<img src="{% static 'images/me.jpg' %}" alt="Profile" srcset="" class="rounded-full w-12 h-12">
</div>
</div>
</div>
<hr>
home.html
{% extends "../base.html" %}
{% block title %}Home Board{% endblock title %}
{% block content %}
{% include "./navbar.html" %}
<div class="px-20" id="main">
<div class="flex justify-between">
<h3 class="mt-5 text-center text-xl text-gray-500 font-bold my-8">Today's Tasks</h3>
<div class="flex justify-center items-center">
<button class="bg-blue-700 rounded text-white font-bold text-sm px-4 py-1">View Calendar</button>
</div>
</div>
<div class="flex">
<div class="flex justify-center items-center">
<button class="bg-blue-700 rounded text-white font-bold text-sm px-4 py-1">All</button>
</div>
<div class="flex justify-center items-center ml-4">
<button class="bg-blue-700 rounded text-white font-bold text-sm px-4 py-1">Completed</button>
</div>
<div class="flex justify-center items-center ml-4">
<button class="bg-blue-700 rounded text-white font-bold text-sm px-4 py-1">Incomplete</button>
</div>
</div>
<div id="all-tasks">
{% include "./todo-list.html" %}
</div>
<div id="completed-tasks">
</div>
<div id="incomplete-tasks">
</div>
</div>
</form>
</div>
</div>
<div>
</div>
{% endblock content %}
views.py
def create_todo(request):
if request.method == "POST":
title = request.POST.get("title")
description = request.POST.get("description")
due_date = request.POST.get("due_date")
todo = Todo.objects.create(title=title, description=description, due_date=due_date)
# todo.save()
todos = Todo.objects.all().order_by("-id")
context = {
"todos": todos,
}
return render(request, "todo/todo-list.html", context)
elif request.method == "GET":
return render(request, "todo/add_task.html")
add_task.html
<div class="flex justify-center">
<div class="w-full">New Task</div>
<div>
<label for="title">Task Title</label>
<input type="text" name="title" id="title">
</div>
</div>
When the page is rendered, it looks like belowImage showing the add_task page rendered dynamically
When i try to reload the page, the contents of the page change to image of the add_task page after me trying to reload it
I thought after reloading the page, the contents on it would remain the same
The way to solve it is to provide entire html template when "non-htmx" request is done.
So in your view, check if request is triggered by htmx and if not, use different template (one that includes add_task.html and extends from base.html)
elif request.method == "GET":
if request.headers.get("HX-Request") == "true":
return render(request, "todo/add_task.html")
return render(request, "todo/add_task_with_base.html")