diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2021-04-15 17:15:28 +0200 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2021-04-21 09:08:34 +0200 |
| commit | 54d5bfa9c5eb3e2936a0e382724869867059fad3 (patch) | |
| tree | ba6af3e8f871fa5c3e8680599000acecde9c8117 /django | |
| parent | 4acce4d95f917d68989e4c1787a11333cc8d0318 (diff) | |
[3.2.x] Fixed #32647 -- Restored multi-row select with shift-modifier in admin changelist.
Regression in 30e59705fc3e3e9e8370b965af794ad6173bf92b.
Backport of 5c73fbb6a93ee214678f02ba4027f18dff49337b from main
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/static/admin/js/actions.js | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js index 3e76ff962a..da1c31085a 100644 --- a/django/contrib/admin/static/admin/js/actions.js +++ b/django/contrib/admin/static/admin/js/actions.js @@ -88,6 +88,16 @@ window.Actions = function(actionCheckboxes, options) { options = Object.assign({}, defaults, options); let list_editable_changed = false; + let lastChecked = null; + let shiftPressed = false; + + document.addEventListener('keydown', (event) => { + shiftPressed = event.shiftKey; + }); + + document.addEventListener('keyup', (event) => { + shiftPressed = event.shiftKey; + }); document.getElementById(options.allToggleId).addEventListener('click', function(event) { checker(actionCheckboxes, options, this.checked); @@ -113,12 +123,28 @@ }); }); + function affectedCheckboxes(target, withModifier) { + const multiSelect = (lastChecked && withModifier && lastChecked !== target); + if (!multiSelect) { + return [target]; + } + const checkboxes = Array.from(actionCheckboxes); + const targetIndex = checkboxes.findIndex(el => el === target); + const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked); + const startIndex = Math.min(targetIndex, lastCheckedIndex); + const endIndex = Math.max(targetIndex, lastCheckedIndex); + const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex)); + return filtered; + }; + Array.from(document.getElementById('result_list').tBodies).forEach(function(el) { el.addEventListener('change', function(event) { const target = event.target; if (target.classList.contains('action-select')) { - target.closest('tr').classList.toggle(options.selectedClass, target.checked); + const checkboxes = affectedCheckboxes(target, shiftPressed); + checker(checkboxes, options, target.checked); updateCounter(actionCheckboxes, options); + lastChecked = target; } else { list_editable_changed = true; } |
