Source code for eucrim.core.widgets
# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2
import django_filters
from itertools import chain
from django.db.models.fields import BLANK_CHOICE_DASH
from django.forms.utils import flatatt
from django.template.loader import render_to_string
from django.utils.encoding import force_str
from django.utils.http import urlencode
from django.utils.translation import gettext as _
[docs]
class DropdownLinkWidget(django_filters.widgets.LinkWidget):
"""
Extend to get a dropdown with links.
To use your own template, overwrite the given one.
"""
label = None
right = False
template = "core/widgets/dropdown_link.html"
[docs]
def get_option_label(self, value, choices=()):
option_label = BLANK_CHOICE_DASH[0][1]
for v, label in chain(self.choices, choices):
if str(v) == value:
option_label = label
break
if option_label == BLANK_CHOICE_DASH[0][1]:
option_label = "All"
return option_label
[docs]
def render(self, name, value, attrs=None, renderer=None, choices=()):
all_choices = list(chain(self.choices, choices))
if len(all_choices) <= 1:
return ""
if value is None:
value = all_choices[0][0]
_id = attrs.pop("id")
final_attrs = flatatt(self.build_attrs(attrs))
value_label = self.get_option_label(value, choices=choices)
options = super().render(
name,
value,
attrs={
"class": "dropdown-menu",
"aria-labelledby": _id,
},
choices=choices,
)
return render_to_string(
self.template,
{
"options": options,
"id": _id,
"attrs": final_attrs,
"value_label": value_label,
"label": self.label,
"right": self.right,
},
)
[docs]
def render_option(self, name, selected_choices, option_value, option_label):
option_value = force_str(option_value)
if option_label == BLANK_CHOICE_DASH[0][1]:
option_label = _("All")
data = self.data.copy()
data[name] = option_value
selected = data == self.data or option_value in selected_choices
try:
url = data.urlencode()
except AttributeError:
url = urlencode(data)
return self.option_string() % {
"attrs": selected
and ' class="dropdown-item selected"'
or 'class="dropdown-item"',
"query_string": url,
"label": force_str(option_label),
}
[docs]
def option_string(self):
return '<li><a %(attrs)s href="?%(query_string)s">%(label)s</a></li>'