feat: Enhance case selection functionality with dedicated select button and improved event handling
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
{% load case_widgets %}
|
||||
|
||||
{% partialdef case-series %}
|
||||
@@ -475,6 +474,7 @@
|
||||
|
||||
<details class="series-move-panel border rounded p-2">
|
||||
<summary class="small fw-semibold">Move selected series to another case</summary>
|
||||
aaoecuthsaoehntu
|
||||
{% if move_series_form %}
|
||||
<form id="move-selected-series-form" class="d-flex flex-column gap-2 mt-2">
|
||||
{{ move_series_form.destination_case }}
|
||||
@@ -498,28 +498,13 @@
|
||||
if (window.__moveSeriesCaseSelectionBound) return;
|
||||
window.__moveSeriesCaseSelectionBound = true;
|
||||
|
||||
function syncMoveSeriesSubmitState() {
|
||||
const form = document.getElementById('move-selected-series-form');
|
||||
const hiddenInput = form ? form.querySelector("[name='destination_case']") : null;
|
||||
const submitBtn = document.getElementById('move-selected-series-submit');
|
||||
if (!hiddenInput || !submitBtn) return;
|
||||
submitBtn.disabled = !hiddenInput.value;
|
||||
}
|
||||
|
||||
document.body.addEventListener('case:selected', async function (e) {
|
||||
try {
|
||||
console.log('Received case:selected event', e);
|
||||
const detail = e.detail || {};
|
||||
const casePk = detail.casePk;
|
||||
const caseTitle = detail.caseTitle || ('Case #' + casePk);
|
||||
function applyMoveCaseSelection(casePk, caseTitle) {
|
||||
if (!casePk) return;
|
||||
|
||||
// Only react to selections from this move panel's widget.
|
||||
if (!e.target || !e.target.closest('#move-selected-series-form')) return;
|
||||
|
||||
const form = document.getElementById('move-selected-series-form');
|
||||
const hiddenInput = form ? form.querySelector("[name='destination_case']") : null;
|
||||
const label = document.getElementById('selected-move-case');
|
||||
const results = document.getElementById('move-series-case-search-results');
|
||||
if (!hiddenInput) return;
|
||||
|
||||
hiddenInput.value = casePk;
|
||||
@@ -528,7 +513,61 @@
|
||||
label.classList.remove('text-muted');
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results.querySelectorAll('.list-group-item[data-case-pk]').forEach(function (item) {
|
||||
item.classList.toggle('active', String(item.getAttribute('data-case-pk')) === String(casePk));
|
||||
});
|
||||
}
|
||||
|
||||
syncMoveSeriesSubmitState();
|
||||
}
|
||||
|
||||
function syncMoveSeriesSubmitState() {
|
||||
const form = document.getElementById('move-selected-series-form');
|
||||
const hiddenInput = form ? form.querySelector("[name='destination_case']") : null;
|
||||
const submitBtn = document.getElementById('move-selected-series-submit');
|
||||
if (!hiddenInput || !submitBtn) return;
|
||||
submitBtn.disabled = !hiddenInput.value;
|
||||
}
|
||||
|
||||
function selectFromRow(row) {
|
||||
if (!row) return;
|
||||
const casePk = row.getAttribute('data-case-pk');
|
||||
const caseTitleEl = row.querySelector('h6');
|
||||
const caseTitle = caseTitleEl ? caseTitleEl.textContent.trim() : ('Case #' + casePk);
|
||||
applyMoveCaseSelection(casePk, caseTitle);
|
||||
}
|
||||
|
||||
// Hard fallback: capture-phase click listener scoped to this widget results.
|
||||
document.addEventListener('click', function (e) {
|
||||
try {
|
||||
const row = e.target.closest('#move-series-case-search-results .list-group-item[data-case-pk]');
|
||||
if (!row) return;
|
||||
if (e.target.closest('a,button,form,input')) return;
|
||||
selectFromRow(row);
|
||||
} catch (err) {
|
||||
console.error('Move series capture click handler error', err);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Mirror uploads-style delegated click handling directly on rows.
|
||||
document.body.addEventListener('click', function (e) {
|
||||
try {
|
||||
const item = e.target.closest('#move-series-case-search-results .list-group-item[data-case-pk]');
|
||||
if (!item) return;
|
||||
if (e.target.closest('a,button,form,input')) return;
|
||||
selectFromRow(item);
|
||||
} catch (err) {
|
||||
console.error('Move series row click handler error', err);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.addEventListener('case:selected', function (e) {
|
||||
try {
|
||||
const detail = e.detail || {};
|
||||
const casePk = detail.casePk;
|
||||
const caseTitle = detail.caseTitle || ('Case #' + casePk);
|
||||
applyMoveCaseSelection(casePk, caseTitle);
|
||||
} catch (err) {
|
||||
console.error('Move series case:selected handler error', err);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
</form>
|
||||
<a class="btn btn-sm btn-outline-secondary ms-2" href="{% url 'atlas:case_detail' case.pk %}" target="_blank" rel="noopener">View</a>
|
||||
{% else %}
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_detail' case.pk %}">View</a>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary case-select-btn" data-case-select="{{ case.pk }}">Select</button>
|
||||
<a class="btn btn-sm btn-outline-secondary ms-2" href="{% url 'atlas:case_detail' case.pk %}">View</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -60,8 +60,14 @@
|
||||
targetEl.addEventListener('click', function(e){
|
||||
var item = e.target.closest('.list-group-item');
|
||||
if (!item || !targetEl.contains(item)) return;
|
||||
// Ignore clicks on interactive elements inside the item (links, buttons, forms, inputs)
|
||||
|
||||
// Explicit select action button should always select the row.
|
||||
if (e.target.closest('.case-select-btn')) {
|
||||
e.preventDefault();
|
||||
} else {
|
||||
// Ignore other interactive elements inside the item (links, buttons, forms, inputs)
|
||||
if (e.target.closest('a,button,form,input')) return;
|
||||
}
|
||||
|
||||
var casePk = item.getAttribute('data-case-pk');
|
||||
if (!casePk) {
|
||||
|
||||
Reference in New Issue
Block a user