Enhance series selection functionality with select/deselect all buttons and improve selection toggle logic

This commit is contained in:
Ross
2026-03-02 13:14:05 +00:00
parent c14ad2dcf7
commit 5d0ff3373d
+48 -13
View File
@@ -199,8 +199,10 @@
// disable action buttons if none selected
const deleteBtn = document.getElementById('delete-uploads-button');
const importBtn = document.getElementById('import-dicoms-sequential-button');
const importIntoCaseBtn = document.getElementById('import-into-case-button');
if (deleteBtn) deleteBtn.disabled = selected === 0;
if (importBtn) importBtn.disabled = selected === 0;
if (importIntoCaseBtn) importIntoCaseBtn.disabled = selected === 0;
}
// Keep count up-to-date on checkbox changes and attribute changes
@@ -288,7 +290,8 @@
checkbox.disabled = true;
checkbox.checked = false;
}
li.querySelector('span')?.onclick = null;
const _sp = li.querySelector('span');
if (_sp) _sp.onclick = null;
li.style.pointerEvents = "none";
li.style.opacity = "0.7";
}
@@ -300,6 +303,39 @@
});
}
// Select / Deselect all series within a study block
document.addEventListener('click', function (e) {
const target = e.target;
if (target.matches('.select-all-btn')) {
const detail = target.closest('.study-block');
if (!detail) return;
const inputs = detail.querySelectorAll('input[name="selection"]');
inputs.forEach(cb => {
if (!cb.disabled) {
cb.checked = true;
const li = cb.closest('.series-item');
if (li) li.classList.add('selected');
cb.dispatchEvent(new Event('change', { bubbles: true }));
}
});
if (typeof updateSelectionCount === 'function') updateSelectionCount();
}
if (target.matches('.deselect-all-btn')) {
const detail = target.closest('.study-block');
if (!detail) return;
const inputs = detail.querySelectorAll('input[name="selection"]');
inputs.forEach(cb => {
if (!cb.disabled) {
cb.checked = false;
const li = cb.closest('.series-item');
if (li) li.classList.remove('selected');
cb.dispatchEvent(new Event('change', { bubbles: true }));
}
});
if (typeof updateSelectionCount === 'function') updateSelectionCount();
}
});
// Listen for `case:selected` events dispatched by the case-search widget and perform the import
document.body.addEventListener('case:selected', async function (e) {
try {
@@ -326,7 +362,7 @@
// Build import URL and POST
const importTemplate = "{% url 'api-1:import_dicoms_case' 0 %}";
const importUrl = importTemplate.replace(/0\/?$/, casePk + '/');
const importUrl = importTemplate.replace(/0\/?$/, casePk );
const form = new URLSearchParams();
for (const s of selectionList) form.append('selection', s);
const orderSeriesInput = document.querySelector('input[name="order-series"]:checked');
@@ -357,18 +393,17 @@
}
});
// Row click toggles selection (avoid when clicking interactive elements inside)
// Row click toggles selection when clicking any non-interactive part of the series card
document.body.addEventListener('click', function (e) {
const el = e.target.closest('.series-left');
if (!el) return;
// ignore clicks on links, buttons or inputs inside the block
if (e.target.closest('a,button,input')) return;
const cb = el.querySelector('input[name="selection"]');
if (!cb || cb.disabled) return;
cb.checked = !cb.checked;
const li = el.closest('li');
if (li) li.classList.toggle('selected', cb.checked);
cb.dispatchEvent(new Event('change', { bubbles: true }));
const item = e.target.closest('.series-item');
if (!item) return;
// ignore clicks on links, buttons, inputs or forms inside the item
if (e.target.closest('a,button,input,form')) return;
const cb = item.querySelector('input[name="selection"]');
if (!cb || cb.disabled) return;
cb.checked = !cb.checked;
item.classList.toggle('selected', cb.checked);
cb.dispatchEvent(new Event('change', { bubbles: true }));
});
</script>