diff --git a/generic/forms.py b/generic/forms.py index cf56377b..04127ae5 100755 --- a/generic/forms.py +++ b/generic/forms.py @@ -658,7 +658,29 @@ class UserUserGroupForm(ModelForm): timeout = setTimeout(() => fetchResults(search.value), 50); }}); - window.addUserToField = function(fieldName, id, text) {{ + // fieldName for this widget instance + const widgetFieldName = '{self.name}'; + + // Add button click delegation: results list buttons have data attributes + results.addEventListener('click', function(e) {{ + const btn = e.target.closest('.user-add-btn'); + if (!btn) return; + const id = btn.getAttribute('data-user-id'); + const text = btn.getAttribute('data-user-text') || btn.textContent.trim(); + const grade = btn.getAttribute('data-user-grade') || ''; + addUserToField(widgetFieldName, id, text, grade); + }}); + + // Wire up the "Add all results" button if present + const addAllBtn = results.parentElement.querySelector('.user-add-all-btn'); + if (addAllBtn) { + addAllBtn.addEventListener('click', function(e) {{ + e.preventDefault(); + addAllFromResults(widgetFieldName); + }}); + } + + window.addUserToField = function(fieldName, id, text, grade) {{ const sel = document.getElementById('id_' + fieldName); if (!sel) return; // prevent duplicate @@ -666,11 +688,12 @@ class UserUserGroupForm(ModelForm): const opt = document.createElement('option'); opt.value = id; opt.selected = true; opt.text = text; sel.appendChild(opt); - // add to visible list + // add to visible list (include grade if provided) const li = document.createElement('li'); li.className = 'list-group-item d-flex justify-content-between align-items-center'; li.id = 'selected_user_' + fieldName + '_' + id; - const span = document.createElement('span'); span.innerHTML = text; + const span = document.createElement('span'); + span.innerHTML = text + (grade ? ' ' + grade + '' : ''); const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'btn btn-sm btn-outline-danger ms-2'; btn.innerText = 'Remove'; btn.addEventListener('click', function() {{ removeUserFromField(fieldName, id); }}); li.appendChild(span); li.appendChild(btn); @@ -692,7 +715,8 @@ class UserUserGroupForm(ModelForm): items.forEach(function(it) {{ const id = it.getAttribute('data-user-id'); const text = it.getAttribute('data-user-text') || it.textContent.trim(); - addUserToField(fieldName, id, text); + const grade = it.getAttribute('data-user-grade') || ''; + addUserToField(fieldName, id, text, grade); }}); }} }})(); diff --git a/generic/templates/generic/partials/user_search_widget_results.html b/generic/templates/generic/partials/user_search_widget_results.html index 62ba7527..e734b723 100644 --- a/generic/templates/generic/partials/user_search_widget_results.html +++ b/generic/templates/generic/partials/user_search_widget_results.html @@ -1,17 +1,22 @@ {% if results %} {% if results %}
- +
{% endif %} {% else %} diff --git a/generic/views.py b/generic/views.py index 885d3691..9ea1409a 100644 --- a/generic/views.py +++ b/generic/views.py @@ -6017,10 +6017,25 @@ def user_search_widget(request): limit = 50 if q in ("*", "%") or q_raw in ("*", "%") else 10 users_qs = users_qs.order_by("last_name", "first_name")[:limit] - results = [ - {"id": u.pk, "text": f"{u.get_full_name() or u.username} - {u.email or ''}"} - for u in users_qs - ] + results = [] + for u in users_qs: + grade = "" + try: + up = getattr(u, "userprofile", None) + if up and getattr(up, "grade", None): + # grade may be a FK object or a simple string depending on model + g = up.grade + grade = getattr(g, "name", str(g)) if g is not None else "" + except Exception: + grade = "" + + results.append( + { + "id": u.pk, + "text": f"{u.get_full_name() or u.username} - {u.email or ''}", + "grade": grade, + } + ) return render( request,