add filter, search text and per page choices
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
@@ -4,12 +4,60 @@
|
|||||||
|
|
||||||
{% 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>
|
||||||
|
|
||||||
|
<form action="" method="GET">
|
||||||
|
<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">
|
||||||
|
<button
|
||||||
|
id="filterDropdownButton"
|
||||||
|
data-dropdown-toggle="filterDropdown"
|
||||||
|
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"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<i class="h-4 w-4 mr-2 fa-solid fa-filter"></i>
|
||||||
|
Filter
|
||||||
|
<i class="-mr-1 ml-1.5 mt-1 w-5 h-5 fa-solid fa-chevron-down"></i>
|
||||||
|
</button>
|
||||||
|
<div id="filterDropdown" class="z-10 hidden w-56 p-3 bg-white rounded-lg shadow dark:bg-gray-700">
|
||||||
|
<h6 class="mb-3 text-sm font-medium text-gray-900 dark:text-white">Beschluss</h6>
|
||||||
|
<ul class="space-y-2 text-sm" aria-labelledby="filterDropdownButton">
|
||||||
|
{% for option in options %}
|
||||||
|
<li class="flex items-center">
|
||||||
|
<input
|
||||||
|
id="item_{{ forloop.counter0 }}"
|
||||||
|
type="checkbox"
|
||||||
|
name="options"
|
||||||
|
value="{{ option.1 }}"
|
||||||
|
{% for selected_option in selected_options %}
|
||||||
|
{% if selected_option in option.1 %}
|
||||||
|
checked
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
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 class="mx-auto max-w-5xl">
|
<div class="mx-auto max-w-5xl">
|
||||||
<div class="overflow-x-scroll shadow rounded">
|
<div class="overflow-x-scroll shadow rounded">
|
||||||
<table class="w-full">
|
<table class="w-full">
|
||||||
@@ -17,7 +65,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="text-left">Nummer</th>
|
<th class="text-left">Nummer</th>
|
||||||
<th class="text-left">Bezeichnung</th>
|
<th class="text-left">Bezeichnung</th>
|
||||||
<!--<th class="text-left">Abstimmungstext</th>-->
|
|
||||||
<th class="text-left">Abstimmungsverhalten</th>
|
<th class="text-left">Abstimmungsverhalten</th>
|
||||||
<th class="text-left">Beschluss</th>
|
<th class="text-left">Beschluss</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
@@ -28,7 +75,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="text-right">{{ result.id }}</td>
|
<td class="text-right">{{ result.id }}</td>
|
||||||
<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>
|
<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>
|
||||||
<!--<td class="text-left">{{ result.voting_text|truncatechars:300 }}</td>-->
|
|
||||||
<td class="text-left">{{ result.voting }}</td>
|
<td class="text-left">{{ result.voting }}</td>
|
||||||
<td class="text-left">{{ result.get_option_display }}</td>
|
<td class="text-left">{{ result.get_option_display }}</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -40,29 +86,39 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if is_paginated %}
|
|
||||||
<div class="mt-4 w-full flex flex-col-reverse sm:flex-row gap-y-4 justify-between items-center">
|
<div class="mt-4 w-full flex flex-col-reverse sm:flex-row gap-y-4 justify-between items-center">
|
||||||
<div class="pagination-container">
|
<div class="flex items-center gap-2">
|
||||||
<div class="pagination">
|
<label for="displaySelector" class="text-gray-700 dark:text-gray-300">Anzeigen:</label>
|
||||||
<span class="step-links">
|
<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 %}
|
{% if page_obj.has_previous %}
|
||||||
<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>
|
<a href="{{ prev_page }}"><i class="fa-solid fa-arrow-left" aria-label="Eine Seite zurück"></i> Zurück</a>
|
||||||
<a href="?page=1">1</a>
|
<a href="{{ first_page }}">1</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<span class="current active">
|
|
||||||
<a href="#" class="active">{{ page_obj.number }}</a>
|
<a href="#" class="active">{{ page_obj.number }}</a>
|
||||||
</span>
|
|
||||||
|
|
||||||
{% if page_obj.has_next %}
|
{% if page_obj.has_next %}
|
||||||
<a href="?page={{ page_obj.paginator.num_pages }}">{{ page_obj.paginator.num_pages }}</a>
|
<a href="{{ last_page }}">{{ page_obj.paginator.num_pages }}</a>
|
||||||
<a href="?page={{ page_obj.next_page_number }}">Vor <i class="fa-solid fa-arrow-right" aria-label="Eine Seite vor"></i></a>
|
<a href="{{ next_page }}">Vor <i class="fa-solid fa-arrow-right" aria-label="Eine Seite vor"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</main>
|
</main>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
Reference in New Issue
Block a user