Add user search functionality for manual trainee matching in bulk update
This commit is contained in:
@@ -33,7 +33,21 @@
|
||||
<td><pre style="margin:0">{{ r.raw }}</pre></td>
|
||||
<td>{{ r.norm_name }}</td>
|
||||
<td>{{ r.grade }}</td>
|
||||
<td>{% if r.matched_user %}<a href="{% url 'account_profile' r.matched_user.username %}">{{ r.matched_user.first_name }} {{ r.matched_user.last_name }}</a>{% else %}<span style="color:red">No match</span>{% endif %}</td>
|
||||
<td>
|
||||
{% if r.matched_user %}
|
||||
<a href="{% url 'account_profile' r.matched_user.username %}">{{ r.matched_user.first_name }} {{ r.matched_user.last_name }}</a>
|
||||
{% else %}
|
||||
<div>
|
||||
<span style="color:red">No match</span>
|
||||
<div>
|
||||
<input type="text" id="user-search-input-{{ r.row_index }}" placeholder="Search users..." style="width:220px" />
|
||||
<button type="button" onclick="searchUsers({{ r.row_index }})">Search</button>
|
||||
</div>
|
||||
<div id="user-results-{{ r.row_index }}"></div>
|
||||
<input type="hidden" name="manual_user_{{ r.row_index }}" id="manual_user_{{ r.row_index }}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ r.supervisor_text }}</td>
|
||||
<td>{% if r.matched_supervisor %}<a href="{% url 'generic:supervisor_detail' r.matched_supervisor.pk %}">{{ r.matched_supervisor.name }}</a>{% else %}<span style="color:red">No match</span>{% endif %}</td>
|
||||
</tr>
|
||||
@@ -48,3 +62,56 @@
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
function searchUsers(rowIndex) {
|
||||
const input = document.getElementById('user-search-input-' + rowIndex);
|
||||
const q = input ? input.value.trim() : '';
|
||||
const resultsDiv = document.getElementById('user-results-' + rowIndex);
|
||||
const hiddenInput = document.getElementById('manual_user_' + rowIndex);
|
||||
resultsDiv.innerHTML = 'Searching...';
|
||||
fetch("{% url 'generic:user_search' %}?q=" + encodeURIComponent(q))
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
resultsDiv.innerHTML = '';
|
||||
if (!data || !data.results || data.results.length === 0) {
|
||||
resultsDiv.innerHTML = '<div><em>No users found</em></div>';
|
||||
return;
|
||||
}
|
||||
const ul = document.createElement('ul');
|
||||
ul.style.listStyle = 'none';
|
||||
ul.style.padding = '0';
|
||||
data.results.forEach(function(item){
|
||||
const li = document.createElement('li');
|
||||
li.style.margin = '4px 0';
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.textContent = 'Select';
|
||||
btn.style.marginLeft = '8px';
|
||||
btn.onclick = function(){
|
||||
hiddenInput.value = item.id;
|
||||
resultsDiv.innerHTML = '<div>Selected: ' + escapeHtml(item.text) + '</div>';
|
||||
};
|
||||
li.innerHTML = '<strong>' + escapeHtml(item.text) + '</strong>';
|
||||
li.appendChild(btn);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
resultsDiv.appendChild(ul);
|
||||
})
|
||||
.catch(function(err){
|
||||
resultsDiv.innerHTML = '<div style="color:red">Error searching users</div>';
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/\"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user