diff --git a/app/apps/common/widgets/tom_select.py b/app/apps/common/widgets/tom_select.py index 399637d..6de3a73 100644 --- a/app/apps/common/widgets/tom_select.py +++ b/app/apps/common/widgets/tom_select.py @@ -14,6 +14,7 @@ class TomSelect(widgets.Select): clear_text=_("Clear"), no_results_text=_("No results..."), checkboxes=False, + group_by=None, *args, **kwargs ): @@ -26,6 +27,7 @@ class TomSelect(widgets.Select): 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) @@ -49,6 +51,81 @@ class TomSelect(widgets.Select): 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