Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/staff/templatetags/table_header_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from django import template
from django.http import HttpRequest

register = template.Library()


@register.inclusion_tag("django_tables2/header.html", takes_context=True)
def render_header(context: dict) -> dict:
url = Url(context["table"].prefixed_order_by_field, context["request"])
for column in context["table"].columns:
sort_url, remove_sort_url, first_sort, descending = url.get_sort_url(
column.name
)
column.ext = {
"sort_url": sort_url,
"remove_sort_url": remove_sort_url,
"first_sort": first_sort,
"descending": descending,
"next": remove_sort_url if not first_sort and descending else sort_url,
}

return context


class Url:
"""
Based on code from:
https://github.com/TheRealVizard/django-table-sort/blob/main/django_table_sort/table.py
"""

def __init__(self, sort_key_name: str, request: HttpRequest):
self.sort_key_name = sort_key_name
self.request = request

def contains_field(self, lookups: list, field: str) -> int:
"""Check if the field is in the sort lookups."""
try:
return lookups.index(field)
except ValueError:
return -1

def get_sort_url(self, field: str) -> tuple[str, str, bool, bool]:
"""Generate the urls to sort the table for the given field."""
lookups = self.request.GET.copy()
removed_lookup = self.request.GET.copy()

first_sort = True
descending = True

if self.sort_key_name in lookups.keys():
current_order = lookups.getlist(self.sort_key_name, [])
removed_order = current_order.copy()
position = self.contains_field(current_order, field)
if position != -1:
first_sort = False
descending = False
current_order[position] = f"-{field}"
removed_order.remove(field)
else:
position = self.contains_field(current_order, f"-{field}")
if position != -1:
first_sort = False
current_order[position] = field
removed_order.remove(f"-{field}")
else:
current_order.append(field)
lookups.setlist(self.sort_key_name, current_order)
if len(removed_order) >= 1:
removed_lookup.setlist(self.sort_key_name, removed_order)
else:
removed_lookup.pop(self.sort_key_name)
else:
lookups.setlist(self.sort_key_name, [field])

return (
lookups.urlencode(),
removed_lookup.urlencode(),
first_sort,
descending,
)
25 changes: 25 additions & 0 deletions src/templates/django_tables2/header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<thead {{ table.attrs.thead.as_html }}>
<tr>
{% for column in table.columns %}
<th {{ column.attrs.th.as_html }}>
{% if column.orderable %}
<a href="?{{ column.ext.next }}"
class="inline-flex items-center gap-1">
{{ column.header }}
{% if column.is_ordered %}
{% if "-" in column.order_by_alias %}
<i class="fa-solid fa-sort-down text-gray-500"></i>
{% else %}
<i class="fa-solid fa-sort-up text-gray-500"></i>
{% endif %}
{% else %}
<i class="fa-solid fa-sort text-gray-400 hover:text-black"></i>
{% endif %}
</a>
{% else %}
{{ column.header }}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
54 changes: 17 additions & 37 deletions src/templates/django_tables2/tailwind_inner.html
Original file line number Diff line number Diff line change
@@ -1,53 +1,33 @@
{% load django_tables2 %}
{% load table_header_tag %}
{% load i18n %}

{% block table %}
<table {% render_attrs table.attrs class="w-full table-auto tailwind-table" %}>
{% block table.thead %}
{% if table.show_header %}
<thead {{ table.attrs.thead.as_html }}>
<tr>
{% for column in table.columns %}
<th {{ column.attrs.th.as_html }}>
{% if column.orderable %}
{% comment%}
If the column is orderable, two small arrows will show next to the column name to signal that it can be sorted.
{% endcomment%}
<a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}"
style="display: inline-flex; align-items: center; gap: 0.5em;">
{{ column.header }}
<i class="fa-solid fa-sort text-gray-500 hover:text-black">
</i></a>
{% else %}
{{ column.header }}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
{% endif %}
{% if table.show_header %}
{% render_header %}
{% endif %}
{% endblock table.thead %}


{% block table.tbody %}
<tbody {{ table.attrs.tbody.as_html }}>
{% for row in table.paginated_rows %}
{% block table.tbody.row %}
<tr {{ row.attrs.as_html }}>
<tr {{ row.attrs.as_html }}>

{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>
{% if column.localize == None %}
{{ cell }}
{% else %}
{% if column.localize %}
{{ cell|localize }}
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>
{% if column.localize == None %}
{{ cell }}
{% else %}
{{ cell|unlocalize }}
{% endif %}
{% endif %} </td>
{% endfor %}
</tr>
{% if column.localize %}
{{ cell|localize }}
{% else %}
{{ cell|unlocalize }}
{% endif %}
{% endif %} </td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
Expand Down