View Issue Details

This bug affects 1 person(s).
 6
IDProjectCategoryView StatusLast Update
19925Bug reportsSurvey editingpublic2025-01-29 15:59
Reporter2BITS_PL Assigned Totibor.pacalat  
PrioritynoneSeverityminor 
Status ready for testingResolutionopen 
Product Version6.6.x 
Summary19925: Multiplication of dropdown-menu DOM element when switching response view mode in LimeSurvey
Description

There is an issue in LimeSurvey where the dropdown-menu DOM element multiplies during response view mode toggling (Expanded/Compact). Each toggle adds multiple instances of the dropdown-menu element to the DOM. This issue occurs in the same context as the previously reported issue with the #pjaxClickInhibitor element.

The prepared fix prevents the multiplication of dropdown-menu elements while maintaining proper DOM refresh functionality. The refresh mechanism has been preserved, even though its necessity is unclear.

Steps To Reproduce

Steps to Reproduce:

  1. Go to demo.limesurvey.org.
  2. Log in as an administrator and open any survey with responses.
  3. Navigate to the response list for the selected survey.
  4. Switch the response view mode from "Expanded" to "Compact" or vice versa.
  5. Repeat the action several times.
  6. Observe in the DOM inspector that the dropdown-menu element multiplies with each toggle.

Expected Behavior:
When switching response view modes, the dropdown-menu element should be properly managed. Its duplication should involve removing previous instances so that only the current instance remains in the DOM.

Attachments:

  1. diff file containing the fixes to resolve the issue.
  2. Location of the affected file: application\extensions\admin\grid\GridActionsWidget\assets\action_dropdown.js.
TagsNo tags attached.
Attached Files
fixed_multiplication_dropdownmenu.diff (1,593 bytes)   
 .../admin/grid/GridActionsWidget/assets/action_dropdown.js       | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js b/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
index 6c904f3a..c9f99fb8 100644
--- a/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
+++ b/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
@@ -11,9 +11,11 @@ LS.actionDropdown = {
             document.querySelectorAll('.ls-dropdown-toggle')
         );
         let body = document.querySelector('body');
+        let uniqueId = 'dropdown-menu-' + Math.random().toString(36).substr(2, 9);
         dropdownElementList.map(function (dropdownToggleEl) {
             let dropdownMenu = dropdownToggleEl.nextElementSibling;
             if (dropdownMenu !== null) {
+                dropdownMenu.setAttribute('data-dropdown-id', uniqueId);
                 new LS.actionDropdown.DropdownClass(dropdownToggleEl, {
                     lsMenuElement: dropdownMenu,
                     boundary: body,
@@ -21,9 +23,16 @@ LS.actionDropdown = {
                         strategy: 'fixed',
                     },
                 });
+
                 body.append(dropdownMenu);
             }
         });
+        document.querySelectorAll('.dropdown-menu').forEach(function (menu) {
+            if (menu.getAttribute('data-dropdown-id') !== uniqueId) {
+                    menu.remove();
+                }
+            }
+        );
     }
 };
 
Bug heat6
Complete LimeSurvey version number (& build)6.8.1
I will donate to the project if issue is resolvedNo
Browser
Database type & versionSQL Server 2022
Server OS (if known)
Webserver software & version (if known)
PHP Versionv8.1.29 NTS x64

Users monitoring this issue

There are no users monitoring this issue.

Activities

2BITS_PL

2BITS_PL

2025-01-20 12:18

reporter   ~81844

The previous fix introduced the removal of dropdown-menu elements that did not have unique identifiers. This caused null errors in Bootstrap scripts, as the removed elements were still referenced by the library's mechanisms (e.g., _getPlacement). As a result, dropdowns stopped working.

Solution
The new version of the code:

  1. Adds unique data-dropdown-id identifiers only for new dropdowns.
  2. Removes only unassociated dropdown-menu elements, leaving the active ones.
  3. Prevents null errors by avoiding uncontrolled removal from the DOM.

Recommendations:
Please test the solution in dynamic environments where dropdowns are added or removed. It’s also worth considering better handling of missing elements in Bootstrap methods like _getPlacement.

I’ve attached the diff file with the fix.

fixed_multiplication_dropdownmenu_v2.diff (2,185 bytes)   
 .../grid/GridActionsWidget/assets/action_dropdown.js | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js b/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
index c53dc16c..26144aec 100644
--- a/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
+++ b/application/extensions/admin/grid/GridActionsWidget/assets/action_dropdown.js
@@ -11,11 +11,18 @@ LS.actionDropdown = {
             document.querySelectorAll('.ls-dropdown-toggle')
         );
         let body = document.querySelector('body');
-        let uniqueId = 'dropdown-menu-' + Math.random().toString(36).substr(2, 9);
+        let existingMenus = new Set();
+
         dropdownElementList.map(function (dropdownToggleEl) {
             let dropdownMenu = dropdownToggleEl.nextElementSibling;
             if (dropdownMenu !== null) {
-                dropdownMenu.setAttribute('data-dropdown-id', uniqueId);
+                if (!dropdownMenu.hasAttribute('data-dropdown-id')) {
+                    let uniqueId = 'dropdown-menu-' + Math.random().toString(36).substr(2, 9);
+                    dropdownMenu.setAttribute('data-dropdown-id', uniqueId);
+                }
+
+                existingMenus.add(dropdownMenu.getAttribute('data-dropdown-id'));
+
                 new LS.actionDropdown.DropdownClass(dropdownToggleEl, {
                     lsMenuElement: dropdownMenu,
                     boundary: body,
@@ -24,13 +31,14 @@ LS.actionDropdown = {
                     },
                 });
 
-                body.append(dropdownMenu);
+                if (!body.contains(dropdownMenu)) {
+                    body.append(dropdownMenu);
+                }
             }
         });
         document.querySelectorAll('.dropdown-menu').forEach(function (menu) {
-            if (menu.getAttribute('data-dropdown-id') !== uniqueId) {
-                    menu.remove();
-                }
+            if (!existingMenus.has(menu.getAttribute('data-dropdown-id'))) {
+                menu.remove();
             }
         );
     }
gabrieljenik

gabrieljenik

2025-01-20 17:26

manager   ~81857

https://github.com/LimeSurvey/LimeSurvey/pull/4139

gabrieljenik

gabrieljenik

2025-01-20 17:27

manager   ~81858

@2BITS_PL

We tried the suggested approach. Didn't worked for us as one of the query selectors, related to removing dropdowns, was catching dropdowns which were not related to the grid.

tibor.pacalat

tibor.pacalat

2025-01-29 15:59

administrator   ~81920

@gabrieljenik when I am on your fix branch, I am getting this issue where the page doesn't reload properly after switching back and forth (extended/compact) a couple of times.

Issue History

Date Modified Username Field Change
2025-01-08 11:23 2BITS_PL New Issue
2025-01-08 11:23 2BITS_PL File Added: fixed_multiplication_dropdownmenu.diff
2025-01-08 14:39 tibor.pacalat Bug heat 0 => 2
2025-01-08 14:40 tibor.pacalat Bug heat 2 => 0
2025-01-08 14:40 tibor.pacalat Assigned To => gabrieljenik
2025-01-08 14:40 tibor.pacalat Status new => assigned
2025-01-20 12:18 2BITS_PL Note Added: 81844
2025-01-20 12:18 2BITS_PL File Added: fixed_multiplication_dropdownmenu_v2.diff
2025-01-20 12:18 2BITS_PL Bug heat 0 => 2
2025-01-20 17:26 gabrieljenik Assigned To gabrieljenik => DenisChenu
2025-01-20 17:26 gabrieljenik Status assigned => ready for code review
2025-01-20 17:26 gabrieljenik Note Added: 81857
2025-01-20 17:26 gabrieljenik Bug heat 2 => 4
2025-01-20 17:27 gabrieljenik Note Added: 81858
2025-01-29 15:14 DenisChenu Assigned To DenisChenu => tibor.pacalat
2025-01-29 15:14 DenisChenu Status ready for code review => ready for testing
2025-01-29 15:59 tibor.pacalat Note Added: 81920
2025-01-29 15:59 tibor.pacalat File Added: Screen-2025-01-29-155821.mp4
2025-01-29 15:59 tibor.pacalat Bug heat 4 => 6