Add grade information to user search results and enhance user addition functionality
This commit is contained in:
+28
-4
@@ -658,7 +658,29 @@ class UserUserGroupForm(ModelForm):
|
|||||||
timeout = setTimeout(() => fetchResults(search.value), 50);
|
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);
|
const sel = document.getElementById('id_' + fieldName);
|
||||||
if (!sel) return;
|
if (!sel) return;
|
||||||
// prevent duplicate
|
// prevent duplicate
|
||||||
@@ -666,11 +688,12 @@ class UserUserGroupForm(ModelForm):
|
|||||||
const opt = document.createElement('option'); opt.value = id; opt.selected = true; opt.text = text;
|
const opt = document.createElement('option'); opt.value = id; opt.selected = true; opt.text = text;
|
||||||
sel.appendChild(opt);
|
sel.appendChild(opt);
|
||||||
|
|
||||||
// add to visible list
|
// add to visible list (include grade if provided)
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.className = 'list-group-item d-flex justify-content-between align-items-center';
|
li.className = 'list-group-item d-flex justify-content-between align-items-center';
|
||||||
li.id = 'selected_user_' + fieldName + '_' + id;
|
li.id = 'selected_user_' + fieldName + '_' + id;
|
||||||
const span = document.createElement('span'); span.innerHTML = text;
|
const span = document.createElement('span');
|
||||||
|
span.innerHTML = text + (grade ? ' <small class="text-muted ms-2">' + grade + '</small>' : '');
|
||||||
const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'btn btn-sm btn-outline-danger ms-2'; btn.innerText = 'Remove';
|
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); }});
|
btn.addEventListener('click', function() {{ removeUserFromField(fieldName, id); }});
|
||||||
li.appendChild(span); li.appendChild(btn);
|
li.appendChild(span); li.appendChild(btn);
|
||||||
@@ -692,7 +715,8 @@ class UserUserGroupForm(ModelForm):
|
|||||||
items.forEach(function(it) {{
|
items.forEach(function(it) {{
|
||||||
const id = it.getAttribute('data-user-id');
|
const id = it.getAttribute('data-user-id');
|
||||||
const text = it.getAttribute('data-user-text') || it.textContent.trim();
|
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);
|
||||||
}});
|
}});
|
||||||
}}
|
}}
|
||||||
}})();
|
}})();
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
{% if results %}
|
{% if results %}
|
||||||
<ul class="list-unstyled mb-0" id="user_search_results_list_{{ field }}">
|
<ul class="list-unstyled mb-0" id="user_search_results_list_{{ field }}">
|
||||||
{% for item in results %}
|
{% for item in results %}
|
||||||
<li class="py-1 d-flex justify-content-between align-items-center" data-user-id="{{ item.id }}" data-user-text="{{ item.text|escapejs }}">
|
<li class="py-1 d-flex justify-content-between align-items-center" data-user-id="{{ item.id }}" data-user-text="{{ item.text|escapejs }}" data-user-grade="{{ item.grade|default_if_none:''|escapejs }}">
|
||||||
<div class="flex-grow-1">{{ item.text|escape }}</div>
|
<div class="flex-grow-1">
|
||||||
|
{{ item.text|escape }}
|
||||||
|
{% if item.grade %}
|
||||||
|
<small class="text-muted ms-2">{{ item.grade|escape }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" class="btn btn-sm btn-primary" onclick="addUserToField('{{ field }}', {{ item.id }}, '{{ item.text|escapejs }}')">Add</button>
|
<button type="button" class="btn btn-sm btn-primary user-add-btn" data-user-id="{{ item.id }}" data-user-text="{{ item.text|escapejs }}" data-user-grade="{{ item.grade|default_if_none:''|escapejs }}">Add</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% if results %}
|
{% if results %}
|
||||||
<div class="mt-2 text-end">
|
<div class="mt-2 text-end">
|
||||||
<button type="button" class="btn btn-sm btn-outline-success" onclick="addAllFromResults('{{ field }}')">Add all results</button>
|
<button type="button" class="btn btn-sm btn-outline-success user-add-all-btn" data-field="{{ field }}">Add all results</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
+19
-4
@@ -6017,10 +6017,25 @@ def user_search_widget(request):
|
|||||||
limit = 50 if q in ("*", "%") or q_raw in ("*", "%") else 10
|
limit = 50 if q in ("*", "%") or q_raw in ("*", "%") else 10
|
||||||
users_qs = users_qs.order_by("last_name", "first_name")[:limit]
|
users_qs = users_qs.order_by("last_name", "first_name")[:limit]
|
||||||
|
|
||||||
results = [
|
results = []
|
||||||
{"id": u.pk, "text": f"{u.get_full_name() or u.username} - {u.email or ''}"}
|
for u in users_qs:
|
||||||
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(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
|||||||
Reference in New Issue
Block a user