Enhance row selection functionality in SelectionTable to support shift-range selection and improve checkbox handling
This commit is contained in:
+33
-4
@@ -59,6 +59,7 @@ class SelectionTable(tables.Table):
|
||||
|
||||
self.caption = self.row_selection_controls
|
||||
|
||||
|
||||
@property
|
||||
def row_selection_controls(self):
|
||||
token = (self.attrs or {}).get('data-selection-token', format(id(self), 'x'))
|
||||
@@ -107,9 +108,9 @@ class SelectionTable(tables.Table):
|
||||
setCheckboxesDisabled(true); hideSelectionColumn();
|
||||
|
||||
table.addEventListener('click', function(e){
|
||||
if (!selectionEnabled) return;
|
||||
var tag = (e.target.tagName || '').toLowerCase();
|
||||
if (['a','button','select','textarea','label'].indexOf(tag) !== -1) return;
|
||||
// Checkbox clicks should always be handled (support shift-range selection),
|
||||
// even when row-selection mode is not enabled. Row clicks to toggle a
|
||||
// checkbox still require selectionEnabled.
|
||||
if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')){
|
||||
var cb = e.target;
|
||||
if (e.shiftKey && lastChecked && lastChecked !== cb){
|
||||
@@ -125,9 +126,37 @@ class SelectionTable(tables.Table):
|
||||
lastChecked = cb;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selectionEnabled) return;
|
||||
var tag = (e.target.tagName || '').toLowerCase();
|
||||
if (['a','button','select','textarea','label'].indexOf(tag) !== -1) return;
|
||||
|
||||
var tr = e.target.closest('tr'); if (!tr || !table.contains(tr)) return;
|
||||
var cb = tr.querySelector('input[type="checkbox"][name="selection"]') || tr.querySelector('input[type="checkbox"]');
|
||||
if (cb && !cb.disabled){ cb.checked = !cb.checked; tr.classList.toggle('table-active', cb.checked); updateSelectedCount(); lastChecked = cb; }
|
||||
if (!cb || cb.disabled) return;
|
||||
|
||||
// If the user shift-clicks on a row, perform range selection
|
||||
if (e.shiftKey && lastChecked && lastChecked !== cb){
|
||||
var checks = findRowCheckboxes();
|
||||
var start = checks.indexOf(lastChecked);
|
||||
var end = checks.indexOf(cb);
|
||||
if (start > -1 && end > -1){
|
||||
if (start > end){ var tmp = start; start = end; end = tmp; }
|
||||
// mirror the checked state of the clicked checkbox
|
||||
var newState = !cb.checked;
|
||||
for (var i = start; i <= end; i++){ if (!checks[i].disabled) checks[i].checked = newState; }
|
||||
updateSelectedCount();
|
||||
// ensure lastChecked follows the clicked checkbox
|
||||
lastChecked = cb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle single row checkbox as before
|
||||
cb.checked = !cb.checked;
|
||||
tr.classList.toggle('table-active', cb.checked);
|
||||
updateSelectedCount();
|
||||
lastChecked = cb;
|
||||
}, true);
|
||||
|
||||
table.addEventListener('change', function(e){ if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')) updateSelectedCount(); }, true);
|
||||
|
||||
Reference in New Issue
Block a user