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 // disable action buttons if none selected
const deleteBtn = document.getElementById('delete-uploads-button'); const deleteBtn = document.getElementById('delete-uploads-button');
const importBtn = document.getElementById('import-dicoms-sequential-button'); const importBtn = document.getElementById('import-dicoms-sequential-button');
const importIntoCaseBtn = document.getElementById('import-into-case-button');
if (deleteBtn) deleteBtn.disabled = selected === 0; if (deleteBtn) deleteBtn.disabled = selected === 0;
if (importBtn) importBtn.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 // Keep count up-to-date on checkbox changes and attribute changes
@@ -288,7 +290,8 @@
checkbox.disabled = true; checkbox.disabled = true;
checkbox.checked = false; checkbox.checked = false;
} }
li.querySelector('span')?.onclick = null; const _sp = li.querySelector('span');
if (_sp) _sp.onclick = null;
li.style.pointerEvents = "none"; li.style.pointerEvents = "none";
li.style.opacity = "0.7"; 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 // Listen for `case:selected` events dispatched by the case-search widget and perform the import
document.body.addEventListener('case:selected', async function (e) { document.body.addEventListener('case:selected', async function (e) {
try { try {
@@ -326,7 +362,7 @@
// Build import URL and POST // Build import URL and POST
const importTemplate = "{% url 'api-1:import_dicoms_case' 0 %}"; 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(); const form = new URLSearchParams();
for (const s of selectionList) form.append('selection', s); for (const s of selectionList) form.append('selection', s);
const orderSeriesInput = document.querySelector('input[name="order-series"]:checked'); 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) { document.body.addEventListener('click', function (e) {
const el = e.target.closest('.series-left'); const item = e.target.closest('.series-item');
if (!el) return; if (!item) return;
// ignore clicks on links, buttons or inputs inside the block // ignore clicks on links, buttons, inputs or forms inside the item
if (e.target.closest('a,button,input')) return; if (e.target.closest('a,button,input,form')) return;
const cb = el.querySelector('input[name="selection"]'); const cb = item.querySelector('input[name="selection"]');
if (!cb || cb.disabled) return; if (!cb || cb.disabled) return;
cb.checked = !cb.checked; cb.checked = !cb.checked;
const li = el.closest('li'); item.classList.toggle('selected', cb.checked);
if (li) li.classList.toggle('selected', cb.checked); cb.dispatchEvent(new Event('change', { bubbles: true }));
cb.dispatchEvent(new Event('change', { bubbles: true }));
}); });
</script> </script>