mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #32647 -- Restored multi-row select with shift-modifier in admin changelist.
Regression in 30e59705fc
.
This commit is contained in:
parent
54e94640ac
commit
5c73fbb6a9
@ -88,6 +88,16 @@
|
|||||||
window.Actions = function(actionCheckboxes, options) {
|
window.Actions = function(actionCheckboxes, options) {
|
||||||
options = Object.assign({}, defaults, options);
|
options = Object.assign({}, defaults, options);
|
||||||
let list_editable_changed = false;
|
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) {
|
document.getElementById(options.allToggleId).addEventListener('click', function(event) {
|
||||||
checker(actionCheckboxes, options, this.checked);
|
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) {
|
Array.from(document.getElementById('result_list').tBodies).forEach(function(el) {
|
||||||
el.addEventListener('change', function(event) {
|
el.addEventListener('change', function(event) {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
if (target.classList.contains('action-select')) {
|
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);
|
updateCounter(actionCheckboxes, options);
|
||||||
|
lastChecked = target;
|
||||||
} else {
|
} else {
|
||||||
list_editable_changed = true;
|
list_editable_changed = true;
|
||||||
}
|
}
|
||||||
|
@ -44,3 +44,6 @@ Bugfixes
|
|||||||
* Fixed a regression in Django 3.2 that caused a crash when decoding a cookie
|
* Fixed a regression in Django 3.2 that caused a crash when decoding a cookie
|
||||||
value, used by ``django.contrib.messages.storage.cookie.CookieStorage``, in
|
value, used by ``django.contrib.messages.storage.cookie.CookieStorage``, in
|
||||||
the pre-Django 3.2 format (:ticket:`32643`).
|
the pre-Django 3.2 format (:ticket:`32643`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 3.2 that stopped the shift-key modifier
|
||||||
|
selecting multiple rows in the admin changelist (:ticket:`32647`).
|
||||||
|
@ -1381,6 +1381,28 @@ class SeleniumTests(AdminSeleniumTestCase):
|
|||||||
self.assertIs(all_selector.get_property('checked'), False)
|
self.assertIs(all_selector.get_property('checked'), False)
|
||||||
self.assertEqual(row.get_attribute('class'), '')
|
self.assertEqual(row.get_attribute('class'), '')
|
||||||
|
|
||||||
|
def test_modifier_allows_multiple_section(self):
|
||||||
|
"""
|
||||||
|
Selecting a row and then selecting another row whilst holding shift
|
||||||
|
should select all rows in-between.
|
||||||
|
"""
|
||||||
|
from selenium.webdriver.common.action_chains import ActionChains
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
|
Parent.objects.bulk_create([Parent(name='parent%d' % i) for i in range(5)])
|
||||||
|
self.admin_login(username='super', password='secret')
|
||||||
|
self.selenium.get(self.live_server_url + reverse('admin:admin_changelist_parent_changelist'))
|
||||||
|
checkboxes = self.selenium.find_elements_by_css_selector('tr input.action-select')
|
||||||
|
self.assertEqual(len(checkboxes), 5)
|
||||||
|
for c in checkboxes:
|
||||||
|
self.assertIs(c.get_property('checked'), False)
|
||||||
|
# Check first row. Hold-shift and check next-to-last row.
|
||||||
|
checkboxes[0].click()
|
||||||
|
ActionChains(self.selenium).key_down(Keys.SHIFT).click(checkboxes[-2]).key_up(Keys.SHIFT).perform()
|
||||||
|
for c in checkboxes[:-2]:
|
||||||
|
self.assertIs(c.get_property('checked'), True)
|
||||||
|
self.assertIs(checkboxes[-1].get_property('checked'), False)
|
||||||
|
|
||||||
def test_select_all_across_pages(self):
|
def test_select_all_across_pages(self):
|
||||||
Parent.objects.bulk_create([Parent(name='parent%d' % i) for i in range(101)])
|
Parent.objects.bulk_create([Parent(name='parent%d' % i) for i in range(101)])
|
||||||
self.admin_login(username='super', password='secret')
|
self.admin_login(username='super', password='secret')
|
||||||
|
Loading…
Reference in New Issue
Block a user