Files
WYGIWYH/app/apps/common/widgets/tom_select.py
2025-11-09 15:31:50 -03:00

158 lines
5.0 KiB
Python

from django.forms import SelectMultiple, widgets
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
class TomSelect(widgets.Select):
def __init__(
self,
attrs=None,
remove_button=False,
remove_button_text=_("Remove"),
create=False,
create_text=_("Add"),
clear_button=True,
clear_text=_("Clear"),
no_results_text=_("No results..."),
checkboxes=False,
group_by=None,
*args,
**kwargs,
):
super().__init__(attrs, *args, **kwargs)
self.remove_button = remove_button
self.remove_button_text = remove_button_text
self.clear_button = clear_button
self.create = create
self.create_text = create_text
self.clear_text = clear_text
self.no_results_text = no_results_text
self.checkboxes = checkboxes
self.group_by = group_by
def build_attrs(self, base_attrs, extra_attrs=None):
attrs = super().build_attrs(base_attrs, extra_attrs)
attrs["data-txt-no-results"] = self.no_results_text
if self.remove_button:
attrs["data-remove-button"] = "true"
attrs["data-txt-remove"] = self.remove_button_text
if self.create:
attrs["data-create"] = "true"
attrs["data-txt-create"] = self.create_text
if self.clear_button:
attrs["data-clear-button"] = "true"
attrs["data-txt-clear"] = self.clear_text
if self.checkboxes:
attrs["data-checkboxes"] = "true"
return attrs
def optgroups(self, name, value, attrs=None):
if not self.group_by:
# If no group_by is set, return all options as a single list without optgroups
return [
(
None,
[
self.create_option(
name,
option_value,
option_label,
(str(option_value) in value),
index,
subindex=None,
attrs=attrs,
)
for index, (option_value, option_label) in enumerate(
self.choices
)
],
0,
)
]
groups = {}
has_selected = False
value = set(value) if value else set()
for index, (option_value, option_label) in enumerate(self.choices):
if option_value is None:
option_value = ""
# Determine the group key
if hasattr(option_value, "instance") and hasattr(
option_value.instance, self.group_by
):
group_key = getattr(option_value.instance, self.group_by) or _(
"Ungrouped"
)
else:
group_key = _("Ungrouped")
group_name = str(group_key) if group_key is not None else None
if isinstance(option_label, (list, tuple)):
choices = option_label
else:
choices = [(option_value, option_label)]
if group_name not in groups:
groups[group_name] = []
for subvalue, sublabel in choices:
selected = (not has_selected or self.allow_multiple_selected) and str(
subvalue
) in value
has_selected |= selected
groups[group_name].append(
self.create_option(
name,
subvalue,
sublabel,
selected,
index,
subindex=None,
attrs=attrs,
)
)
optgroups = []
for group_name, subgroup in groups.items():
optgroups.append((group_name, subgroup, 0))
return optgroups
class TomSelectMultiple(SelectMultiple, TomSelect):
pass
class TransactionSelect(TomSelect):
def __init__(self, income: bool = True, expense: bool = True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.load_income = income
self.load_expense = expense
self.create = False
def build_attrs(self, base_attrs, extra_attrs=None):
attrs = super().build_attrs(base_attrs, extra_attrs)
if self.load_income and self.load_expense:
attrs["data-load"] = reverse("transactions_search")
elif self.load_income and not self.load_expense:
attrs["data-load"] = reverse(
"transactions_search", kwargs={"filter_type": "income"}
)
elif self.load_expense and not self.load_income:
attrs["data-load"] = reverse(
"transactions_search", kwargs={"filter_type": "expenses"}
)
return attrs