From b0ed619303d2fb723330ca9efa3acf23d49f1d19 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 21 Sep 2021 19:58:00 +0200 Subject: [PATCH] Fixed #33083 -- Fixed selecting all items in the admin changelist when actions are both top and bottom. Thanks Benjamin Locher for the report. Regression in 30e59705fc3e3e9e8370b965af794ad6173bf92b. --- django/contrib/admin/static/admin/js/actions.js | 11 ++++++++--- docs/releases/3.2.8.txt | 4 ++++ tests/admin_changelist/admin.py | 1 + tests/admin_changelist/tests.py | 14 +++++++++----- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js index 5aee34ea5e..20a5c14353 100644 --- a/django/contrib/admin/static/admin/js/actions.js +++ b/django/contrib/admin/static/admin/js/actions.js @@ -36,7 +36,10 @@ function clearAcross(options) { reset(options); - document.querySelector(options.acrossInput).value = 0; + const acrossInputs = document.querySelectorAll(options.acrossInput); + acrossInputs.forEach(function(acrossInput) { + acrossInput.value = 0; + }); document.querySelector(options.actionContainer).classList.remove(options.selectedClass); } @@ -107,8 +110,10 @@ document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) { el.addEventListener('click', function(event) { event.preventDefault(); - const acrossInput = document.querySelector(options.acrossInput); - acrossInput.value = 1; + const acrossInputs = document.querySelectorAll(options.acrossInput); + acrossInputs.forEach(function(acrossInput) { + acrossInput.value = 1; + }); showClear(options); }); }); diff --git a/docs/releases/3.2.8.txt b/docs/releases/3.2.8.txt index 8494b292cb..cec9dffd0c 100644 --- a/docs/releases/3.2.8.txt +++ b/docs/releases/3.2.8.txt @@ -11,3 +11,7 @@ Bugfixes * Fixed a bug in Django 3.2 that caused incorrect links on read-only fields in admin (:ticket:`33077`). + +* Fixed a regression in Django 3.2 that caused incorrect selection of items + across all pages when actions were placed both on the top and bottom of the + admin change-list view (:ticket:`33083`). diff --git a/tests/admin_changelist/admin.py b/tests/admin_changelist/admin.py index 0397e8557a..f8051f64fa 100644 --- a/tests/admin_changelist/admin.py +++ b/tests/admin_changelist/admin.py @@ -134,6 +134,7 @@ class NoListDisplayLinksParentAdmin(admin.ModelAdmin): list_display_links = None list_display = ['name'] list_editable = ['name'] + actions_on_bottom = True site.register(Parent, NoListDisplayLinksParentAdmin) diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index e0486b37f8..7a567ebc10 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -1481,12 +1481,13 @@ class SeleniumTests(AdminSeleniumTestCase): question = self.selenium.find_element_by_css_selector('.actions > .question') clear = self.selenium.find_element_by_css_selector('.actions > .clear') select_all = self.selenium.find_element_by_id('action-toggle') - select_across = self.selenium.find_element_by_name('select_across') + select_across = self.selenium.find_elements_by_name('select_across') self.assertIs(question.is_displayed(), False) self.assertIs(clear.is_displayed(), False) self.assertIs(select_all.get_property('checked'), False) - self.assertEqual(select_across.get_property('value'), '0') + for hidden_input in select_across: + self.assertEqual(hidden_input.get_property('value'), '0') self.assertIs(selection_indicator.is_displayed(), True) self.assertEqual(selection_indicator.text, '0 of 100 selected') self.assertIs(select_all_indicator.is_displayed(), False) @@ -1495,7 +1496,8 @@ class SeleniumTests(AdminSeleniumTestCase): self.assertIs(question.is_displayed(), True) self.assertIs(clear.is_displayed(), False) self.assertIs(select_all.get_property('checked'), True) - self.assertEqual(select_across.get_property('value'), '0') + for hidden_input in select_across: + self.assertEqual(hidden_input.get_property('value'), '0') self.assertIs(selection_indicator.is_displayed(), True) self.assertEqual(selection_indicator.text, '100 of 100 selected') self.assertIs(select_all_indicator.is_displayed(), False) @@ -1504,7 +1506,8 @@ class SeleniumTests(AdminSeleniumTestCase): self.assertIs(question.is_displayed(), False) self.assertIs(clear.is_displayed(), True) self.assertIs(select_all.get_property('checked'), True) - self.assertEqual(select_across.get_property('value'), '1') + for hidden_input in select_across: + self.assertEqual(hidden_input.get_property('value'), '1') self.assertIs(selection_indicator.is_displayed(), False) self.assertIs(select_all_indicator.is_displayed(), True) @@ -1512,7 +1515,8 @@ class SeleniumTests(AdminSeleniumTestCase): self.assertIs(question.is_displayed(), False) self.assertIs(clear.is_displayed(), False) self.assertIs(select_all.get_property('checked'), False) - self.assertEqual(select_across.get_property('value'), '0') + for hidden_input in select_across: + self.assertEqual(hidden_input.get_property('value'), '0') self.assertIs(selection_indicator.is_displayed(), True) self.assertEqual(selection_indicator.text, '0 of 100 selected') self.assertIs(select_all_indicator.is_displayed(), False)