Enhance case search results: add data attributes for case identification and implement client-side removal of cases from search results after addition to collection

This commit is contained in:
Ross
2025-11-16 23:25:35 +00:00
parent 0193daf166
commit 712ecec25d
3 changed files with 46 additions and 4 deletions
@@ -2,8 +2,8 @@
{% if q %}
{% if cases and cases.exists %}
<div class="list-group mb-2">
{% for case in cases %}
<div class="list-group-item d-flex justify-content-between align-items-center">
{% for case in cases %}
<div class="list-group-item d-flex justify-content-between align-items-center" data-case-pk="{{ case.pk }}">
<div class="flex-fill me-3">
<div class="fw-semibold">{{ case.title }}</div>
<div class="small text-muted">{% if case.description %}{{ case.description|truncatechars:100 }}{% endif %}</div>
@@ -28,7 +28,7 @@
<div class="small text-muted mb-1">Recently created</div>
<div class="list-group">
{% for case in recent_cases %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div class="list-group-item d-flex justify-content-between align-items-center" data-case-pk="{{ case.pk }}">
<div class="flex-fill me-3">
<div class="fw-semibold">{{ case.title }}</div>
<div class="small text-muted">{% if case.description %}{{ case.description|truncatechars:100 }}{% endif %}</div>
@@ -15,3 +15,32 @@
</div>
</div>
<script>
(function(){
// Robust fallback: ensure repeated searches always work by using htmx.ajax when available.
try {
var input = document.getElementById('case-search-input');
if (!input) return;
var timer = null;
input.addEventListener('input', function(){
if (timer) clearTimeout(timer);
timer = setTimeout(function(){
try {
var q = encodeURIComponent(input.value || '');
var url = "{% url 'atlas:case_search' %}?q=" + q + "&collection={{ collection.pk }}";
if (window.htmx && typeof window.htmx.ajax === 'function') {
window.htmx.ajax('GET', url, { target: '#case-search-results', swap: 'innerHTML' });
} else {
// fallback to fetch
fetch(url, { credentials: 'same-origin' }).then(function(r){ return r.text(); }).then(function(html){
var el = document.getElementById('case-search-results');
if (el) el.innerHTML = html;
}).catch(function(e){ console.error('case search fetch error', e); });
}
} catch(e) { console.error(e); }
}, 400);
});
} catch(e) { console.error('case search widget init error', e); }
})();
</script>
+14 -1
View File
@@ -1169,7 +1169,20 @@ def add_case_to_collection(request, collection_id):
},
request=request,
)
return HttpResponse(rendered)
# Also instruct the client to remove this case from any visible search/recent lists
remove_script = (
'<script>'
'(function(){'
'try {'
"var pk = '%s';" % case.pk +
"document.querySelectorAll('#case-search-results [data-case-pk=\"' + pk + '\"]').forEach(function(el){ el.remove(); });" +
"document.querySelectorAll('#case-search-results input[name=\"case\"][value=\"' + pk + '\"]').forEach(function(inp){ var li = inp.closest('.list-group-item'); if (li) li.remove(); });" +
'} catch(e) { console.error("remove added case from search error", e); }'
'})();'
'</script>'
)
return HttpResponse(rendered + remove_script)
# if request.method == "POST":