Home > Software engineering >  Hx-push-url doesn’t work on back button click
Hx-push-url doesn’t work on back button click

Time:03-05

I am trying to integrate Htmx with django and achieve single page application behaviour. I am rewritting Djangoproject.com poll app with htmx. When I click on detail page link, content loads, htmx push a new url in address bar. When I press back button, it took me to index page perfectly for the first time, after that if I again go to detail page and click back button, url shows of the index, button index content doesn’t load, content remains same as detail page. Here is my code

views.py

def index(request):
    latest_question_list = Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    if request.headers.get("Hx-Request") is not None:
        return render(request, 'main/index/index.html', context)
    else:
        return render(request, 'main/index/index-full.html', context)
    
    
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    print(request.headers.get("Hx-Request"))
    if request.headers.get("Hx-Request") is not None:
        return render(request, 'main/detail/detail.html', {'question': question})
    else:
        return render(request, 'main/detail/detail-full.html', {'question': question})
    

index.html

<div id="index" >

    {% if latest_question_list %}
    <ul>
        {% for question in latest_question_list %}
        <li><div  hx-get="{% url 'main:detail' question.id %}" hx-push-url="true" hx-target="#index" hx-swap="outerHTML">{{ question.question_text }}</div></li>
        {% endfor %}
    </ul>
    {% else %}
    <p>
        No polls are available.
    </p>
    {% endif %}

</div>

index-full.html

{% extends 'base.html' %}
{% block content %}
{% include 'main/index/index.html' %}
{% endblock content %}

detail.html

<div id="detail" >

    <form action="{% url 'main:vote' question.id %}" method="post">
        {% csrf_token %}
        <fieldset>
            <legend><h1>{{ question.question_text }}</h1></legend>
            {% if error_message %}<p>
                <strong>{{ error_message }}</strong>
            </p>
            {% endif %}
            {% for choice in question.choice_set.all %}
            <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
            <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
            {% endfor %}
        </fieldset>
        <input type="submit" value="Vote">
    </form>

</div>


detail-full.html

{% extends 'base.html' %}
{% block content %}
{% include 'main/detail/detail.html %}
{% endblock content %}

I found no error in browser console, no error in terminal

Now, I know I can put a back button in detail page that can took me to index page. But user won't use that, they will just use the back button on their device.

CodePudding user response:

Adding this javascript code you can reload the page when the user click the back button:

var auxBack = performance.getEntriesByType("navigation");

if (auxBack[0].type === "back_forward") {
    location.reload(true);
}
  • Related