Refactor UserUserGroupForm to use a reusable UserSearchSelectMultipleWidget for improved user selection and search functionality
This commit is contained in:
+13
-14
@@ -556,20 +556,16 @@ class UserUserGroupModelChoiceField(ModelMultipleChoiceField):
|
|||||||
return f"{obj.username} ({obj.userprofile.grade}) [{obj.email}]"
|
return f"{obj.username} ({obj.userprofile.grade}) [{obj.email}]"
|
||||||
|
|
||||||
|
|
||||||
class UserUserGroupForm(ModelForm):
|
class UserSearchSelectMultipleWidget:
|
||||||
class UserSearchSelectMultiple(object):
|
"""Reusable lightweight widget renderer for a searchable multi-user selector.
|
||||||
"""
|
|
||||||
Lightweight widget renderer for a searchable multi-user selector.
|
Usage: instantiate with (name, value) where value is an iterable of user ids
|
||||||
Renders a hidden <select multiple> containing selected user ids and
|
and call .render() to get the HTML fragment. This mirrors the previous
|
||||||
a search box with results. Uses a small inline script to fetch
|
nested widget but is available module-wide for reuse.
|
||||||
results from the `generic:user_search_widget` endpoint and add/remove
|
|
||||||
users from the selection.
|
|
||||||
This keeps implementation simple and avoids external JS dependencies.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, value):
|
def __init__(self, name, value):
|
||||||
self.name = name
|
self.name = name
|
||||||
# value is a list of selected user ids
|
|
||||||
self.value = value or []
|
self.value = value or []
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
@@ -578,13 +574,11 @@ class UserUserGroupForm(ModelForm):
|
|||||||
results_id = f"user_search_results_{self.name}"
|
results_id = f"user_search_results_{self.name}"
|
||||||
selected_list_id = f"selected_users_{self.name}"
|
selected_list_id = f"selected_users_{self.name}"
|
||||||
|
|
||||||
# Build initial options for selected users
|
|
||||||
users = User.objects.filter(pk__in=self.value) if self.value else []
|
users = User.objects.filter(pk__in=self.value) if self.value else []
|
||||||
options_html = ""
|
options_html = ""
|
||||||
selected_html = ""
|
selected_html = ""
|
||||||
for u in users:
|
for u in users:
|
||||||
options_html += f'<option value="{u.pk}" selected>{u.get_full_name() or u.username} - {u.email}</option>'
|
options_html += f'<option value="{u.pk}" selected>{u.get_full_name() or u.username} - {u.email}</option>'
|
||||||
# include grade display in the selected list if available
|
|
||||||
grade_text = ""
|
grade_text = ""
|
||||||
try:
|
try:
|
||||||
up = getattr(u, "userprofile", None)
|
up = getattr(u, "userprofile", None)
|
||||||
@@ -605,10 +599,10 @@ class UserUserGroupForm(ModelForm):
|
|||||||
|
|
||||||
url = reverse("generic:user_search_widget")
|
url = reverse("generic:user_search_widget")
|
||||||
|
|
||||||
# Build a small grade filter select
|
|
||||||
grades_options = '<option value="">All grades</option>'
|
grades_options = '<option value="">All grades</option>'
|
||||||
try:
|
try:
|
||||||
from generic.models import UserGrades
|
from generic.models import UserGrades
|
||||||
|
|
||||||
grades_qs = UserGrades.objects.all()
|
grades_qs = UserGrades.objects.all()
|
||||||
for g in grades_qs:
|
for g in grades_qs:
|
||||||
grades_options += f'<option value="{g.pk}">{g.name}</option>'
|
grades_options += f'<option value="{g.pk}">{g.name}</option>'
|
||||||
@@ -776,6 +770,11 @@ class UserUserGroupForm(ModelForm):
|
|||||||
|
|
||||||
return mark_safe(html)
|
return mark_safe(html)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UserUserGroupForm(ModelForm):
|
||||||
|
# Use module-level UserSearchSelectMultipleWidget for rendering the users field
|
||||||
|
|
||||||
users = UserUserGroupModelChoiceField(
|
users = UserUserGroupModelChoiceField(
|
||||||
required=False,
|
required=False,
|
||||||
queryset=User.objects.all(),
|
queryset=User.objects.all(),
|
||||||
@@ -808,7 +807,7 @@ class UserUserGroupForm(ModelForm):
|
|||||||
# store attrs so template helpers can inspect them
|
# store attrs so template helpers can inspect them
|
||||||
self.attrs = attrs or {}
|
self.attrs = attrs or {}
|
||||||
value = value or []
|
value = value or []
|
||||||
widget = UserUserGroupForm.UserSearchSelectMultiple(name, value)
|
widget = UserSearchSelectMultipleWidget(name, value)
|
||||||
return widget.render()
|
return widget.render()
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
|
|||||||
Reference in New Issue
Block a user