add filter, search text and per page choices

This commit is contained in:
2025-03-05 15:43:20 +01:00
parent c6684122ea
commit 97c01c4a97
2 changed files with 173 additions and 52 deletions

View File

@@ -231,6 +231,71 @@ class ResolutionListView(LoginRequiredMixin, ListView):
ordering = ["-id"] ordering = ["-id"]
paginate_by = 10 paginate_by = 10
_per_page = 10
_per_page_lst = ["10", "20", "50", "Alle"]
def get(self, request, *args, **kwargs):
self.q = request.GET.get("q", "")
self.options_filters = request.GET.getlist("options", [])
self._per_page = request.GET.get("paginate_by", "10")
if self._per_page == "Alle":
self.paginate_by = None
else:
self.paginate_by = self._per_page
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["q"] = self.q
# Add selected and all options
context["options"] = Resolution.Option.choices
context["selected_options"] = self.options_filters
# Add current per page value and list
context["per_page"] = self._per_page
context["per_page_values"] = self._per_page_lst
# Add paginator links
if context["is_paginated"]:
_page_obj = context["page_obj"]
base_url = "?"
for option in self.options_filters:
base_url += f"options={option}&".replace(" ", "+")
if self.q:
base_url += f"q={self.q}&".replace(" ", "+")
end_url = f"paginate_by={self._per_page}"
if _page_obj.has_previous():
context["prev_page"] = (
f"{base_url}page={_page_obj.previous_page_number()}&{end_url}"
)
context["first_page"] = f"{base_url}page=1&{end_url}"
if _page_obj.has_next():
context["next_page"] = f"{base_url}page={_page_obj.next_page_number()}&{end_url}"
context["last_page"] = f"{base_url}page={_page_obj.paginator.num_pages}&{end_url}"
return context
def get_queryset(self):
qs = super().get_queryset()
if self.q:
qs = qs.filter(Q(name__icontains=self.q) | Q(voting_text__icontains=self.q))
if self.options_filters:
filter_lst = [
elem[0] for elem in Resolution.Option.choices if elem[1] in self.options_filters
]
qs = qs.filter(option__in=filter_lst)
return qs
class ResolutionUpdateView(LoginRequiredMixin, UpdateView): class ResolutionUpdateView(LoginRequiredMixin, UpdateView):

View File

@@ -4,65 +4,121 @@
{% block content %} {% block content %}
<!-- Main Content --> <!-- Main Content -->
<main class="container mx-auto w-full px-4 my-8 flex-1"> <main class="container mx-auto w-full px-4 my-8 flex-1 max-w-5xl">
<h1 class="page-title">Beschlusssammlung</h1> <h1 class="page-title">Beschlusssammlung</h1>
<a href="{% url 'finance:resolution_create' %}" class="page-subtitle block btn-small btn-primary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto"> <a href="{% url 'finance:resolution_create' %}" class="page-subtitle block btn-small btn-primary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto">
<i class="fa-solid fa-plus mr-1"></i> Beschluss eingeben <i class="fa-solid fa-plus mr-1"></i> Beschluss eingeben
</a> </a>
<div class="mx-auto max-w-5xl"> <form action="" method="GET">
<div class="overflow-x-scroll shadow rounded"> <div class="grid grid-cols-1 gap-x-6 gap-y-6 lg:grid-cols-6 sm:grid-cols-3 pb-6 lg:pt-0 pt-4">
<table class="w-full"> <button
<thead> id="filterDropdownButton"
<tr> data-dropdown-toggle="filterDropdown"
<th class="text-left">Nummer</th> class="w-full md:w-auto flex items-center justify-center py-2 px-4 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
<th class="text-left">Bezeichnung</th> type="button"
<!--<th class="text-left">Abstimmungstext</th>--> >
<th class="text-left">Abstimmungsverhalten</th> <i class="h-4 w-4 mr-2 fa-solid fa-filter"></i>
<th class="text-left">Beschluss</th> Filter
<th></th> <i class="-mr-1 ml-1.5 mt-1 w-5 h-5 fa-solid fa-chevron-down"></i>
</tr> </button>
</thead> <div id="filterDropdown" class="z-10 hidden w-56 p-3 bg-white rounded-lg shadow dark:bg-gray-700">
<tbody> <h6 class="mb-3 text-sm font-medium text-gray-900 dark:text-white">Beschluss</h6>
{% for result in object_list %} <ul class="space-y-2 text-sm" aria-labelledby="filterDropdownButton">
<tr> {% for option in options %}
<td class="text-right">{{ result.id }}</td> <li class="flex items-center">
<td class="text-blue-700 dark:text-blue-200 no-underline hover:underline"><a href="{% url 'finance:resolution_detail' result.id %}">{{ result.name }}</a></td> <input
<!--<td class="text-left">{{ result.voting_text|truncatechars:300 }}</td>--> id="item_{{ forloop.counter0 }}"
<td class="text-left">{{ result.voting }}</td> type="checkbox"
<td class="text-left">{{ result.get_option_display }}</td> name="options"
<td> value="{{ option.1 }}"
<a href="{% url 'finance:resolution_update' result.id %}" class="btn btn-small btn-tertiary"><i class="fa-solid fa-pen-to-square" aria-label="Bearbeiten" title="Bearbeiten"></i></a> {% for selected_option in selected_options %}
</td> {% if selected_option in option.1 %}
</tr> checked
{% endfor %} {% endif %}
</tbody> {% endfor %}
</table> class="w-4 h-4 bg-gray-100 border-gray-300 rounded text-primary-600 focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
>
<label for="item_{{ forloop.counter0 }}" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-100">{{ option.1 }}</label>
</li>
{% endfor %}
</ul>
</div>
<div class="col-span-2">
<input
type="text"
name="q"
value="{{ q }}"
placeholder="Suche"
class="w-full"
>
</div>
<button type="submit" class="block btn btn-primary" name="" value="Submit">Anwenden</button>
</div> </div>
{% if is_paginated %} <div class="mx-auto max-w-5xl">
<div class="mt-4 w-full flex flex-col-reverse sm:flex-row gap-y-4 justify-between items-center"> <div class="overflow-x-scroll shadow rounded">
<div class="pagination-container"> <table class="w-full">
<div class="pagination"> <thead>
<span class="step-links"> <tr>
{% if page_obj.has_previous %} <th class="text-left">Nummer</th>
<a href="?page={{ page_obj.previous_page_number }}"><i class="fa-solid fa-arrow-left" aria-label="Eine Seite zurück"></i> Zurück</a> <th class="text-left">Bezeichnung</th>
<a href="?page=1">1</a> <th class="text-left">Abstimmungsverhalten</th>
{% endif %} <th class="text-left">Beschluss</th>
<th></th>
<span class="current active"> </tr>
<a href="#" class="active">{{ page_obj.number }}</a> </thead>
</span> <tbody>
{% for result in object_list %}
{% if page_obj.has_next %} <tr>
<a href="?page={{ page_obj.paginator.num_pages }}">{{ page_obj.paginator.num_pages }}</a> <td class="text-right">{{ result.id }}</td>
<a href="?page={{ page_obj.next_page_number }}">Vor <i class="fa-solid fa-arrow-right" aria-label="Eine Seite vor"></i></a> <td class="text-blue-700 dark:text-blue-200 no-underline hover:underline"><a href="{% url 'finance:resolution_detail' result.id %}">{{ result.name }}</a></td>
{% endif %} <td class="text-left">{{ result.voting }}</td>
</span> <td class="text-left">{{ result.get_option_display }}</td>
</div> <td>
</div> <a href="{% url 'finance:resolution_update' result.id %}" class="btn btn-small btn-tertiary"><i class="fa-solid fa-pen-to-square" aria-label="Bearbeiten" title="Bearbeiten"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
{% endif %}
</div> <div class="mt-4 w-full flex flex-col-reverse sm:flex-row gap-y-4 justify-between items-center">
<div class="flex items-center gap-2">
<label for="displaySelector" class="text-gray-700 dark:text-gray-300">Anzeigen:</label>
<select id="displaySelector" name="paginate_by" class="text-sm">
{% for elem in per_page_values %}
<option
value={{ elem }}
{% if per_page == elem %}
selected
{% endif %}
>{{ elem }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-small btn-primary" name="" value="Submit"><i class="fa-solid fa-arrows-rotate"></i></button>
</div>
{% if is_paginated %}
<div class="pagination pagination-container">
{% if page_obj.has_previous %}
<a href="{{ prev_page }}"><i class="fa-solid fa-arrow-left" aria-label="Eine Seite zurück"></i> Zurück</a>
<a href="{{ first_page }}">1</a>
{% endif %}
<a href="#" class="active">{{ page_obj.number }}</a>
{% if page_obj.has_next %}
<a href="{{ last_page }}">{{ page_obj.paginator.num_pages }}</a>
<a href="{{ next_page }}">Vor <i class="fa-solid fa-arrow-right" aria-label="Eine Seite vor"></i></a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</form>
</main> </main>
{% endblock content %} {% endblock content %}