Pagination breaks JavaScript view toggle - table/boxes view resets on page change

I have a page with pagination and a JavaScript toggle that switches between table and boxes view. The toggle works fine, but when I navigate to another page (page 2, 3, etc.), it always resets back to the default boxes view instead of maintaining the current view state which is a table.

How can I preserve the view state (table vs boxes) across pagination?

Current behavior:

  1. User switches to table view
  2. User clicks “next page”
  3. Page loads but resets to boxes view (not desired)

Desired behavior: Stay in table view across all pages.

<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

<!-- The toggle that breaks on pagination -->
{% for application in page_obj %}
    <!-- both table and boxes loop through page_obj -->
{% endfor %}
// This always resets to boxes on page load
boxes.style.display = 'grid';
tables.style.display = 'none';
let isBoxes = true;

toggleTable.addEventListener('click', function(){
    if(isBoxes){
        boxes.style.display = 'none';
        tables.style.display = 'block';
        isBoxes = false;
    } else {
        boxes.style.display = 'grid';
        tables.style.display = 'none';
        isBoxes = true;
    }
});
def track_applications(request):
    job_list = applications.objects.filter(user=request.user)
    paginator = Paginator(job_list, 3)
    page_obj = paginator.get_page(request.GET.get("page"))
    return render(request, "template.html", {'page_obj': page_obj})

This would be the expected behavior, since there is no “state” maintained between page reloads. “View state” such as this needs to be establish on the server when a full page is replaced.

You’ve got at least three options for solving this:

  • Change your pagination links to include an additional parameter (e.g. current_state). You view then needs to check for this parameter and set it in the appropriate places of the page being returned.

    • You could also store the current view state in the user’s session. (This is the same basic idea as the one above, except it makes the submission of the additional parameter optional. The view would use the session setting for every page except when it is changed.)
  • Store the setting in a cookie. Your JavaScript then becomes responsible for reading that cookie on every request, looking for the view state setting.

  • Change your pagination to use AJAX-style requests to only load a partial page, perhaps using a library like HTMX. (This is our preferred solution.)