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
|
self.caption = self.row_selection_controls
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def row_selection_controls(self):
|
def row_selection_controls(self):
|
||||||
token = (self.attrs or {}).get('data-selection-token', format(id(self), 'x'))
|
token = (self.attrs or {}).get('data-selection-token', format(id(self), 'x'))
|
||||||
@@ -107,9 +108,9 @@ class SelectionTable(tables.Table):
|
|||||||
setCheckboxesDisabled(true); hideSelectionColumn();
|
setCheckboxesDisabled(true); hideSelectionColumn();
|
||||||
|
|
||||||
table.addEventListener('click', function(e){
|
table.addEventListener('click', function(e){
|
||||||
if (!selectionEnabled) return;
|
// Checkbox clicks should always be handled (support shift-range selection),
|
||||||
var tag = (e.target.tagName || '').toLowerCase();
|
// even when row-selection mode is not enabled. Row clicks to toggle a
|
||||||
if (['a','button','select','textarea','label'].indexOf(tag) !== -1) return;
|
// checkbox still require selectionEnabled.
|
||||||
if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')){
|
if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')){
|
||||||
var cb = e.target;
|
var cb = e.target;
|
||||||
if (e.shiftKey && lastChecked && lastChecked !== cb){
|
if (e.shiftKey && lastChecked && lastChecked !== cb){
|
||||||
@@ -125,9 +126,37 @@ class SelectionTable(tables.Table):
|
|||||||
lastChecked = cb;
|
lastChecked = cb;
|
||||||
return;
|
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 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"]');
|
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);
|
}, true);
|
||||||
|
|
||||||
table.addEventListener('change', function(e){ if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')) updateSelectedCount(); }, 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