]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Fix: Click on input outside of dropdown-menu prevents dropdown from closing (#33920)
authoralpadev <2838324+alpadev@users.noreply.github.com>
Tue, 11 May 2021 06:09:00 +0000 (08:09 +0200)
committerGitHub <noreply@github.com>
Tue, 11 May 2021 06:09:00 +0000 (09:09 +0300)
* test: add test if user clicks on input not contained within dropdown-menu

* fix: click on inputs that are not contained within dropdown-menu prevent dropdown from closing

js/src/dropdown.js
js/tests/unit/dropdown.spec.js

index 8bd3f01e70519189e91a2706fd902dbf18d567e5..f56ab201b7cef33fa0eb86d6427638574ab1fe9d 100644 (file)
@@ -408,14 +408,8 @@ class Dropdown extends BaseComponent {
   }
 
   static clearMenus(event) {
-    if (event) {
-      if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {
-        return
-      }
-
-      if (/input|select|option|textarea|form/i.test(event.target.tagName)) {
-        return
-      }
+    if (event && (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY))) {
+      return
     }
 
     const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
@@ -445,8 +439,8 @@ class Dropdown extends BaseComponent {
           continue
         }
 
-        // Tab navigation through the dropdown menu shouldn't close the menu
-        if (event.type === 'keyup' && event.key === TAB_KEY && context._menu.contains(event.target)) {
+        // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
+        if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {
           continue
         }
 
index 57989059d156d27c30e9ff0cb24200d40332d166..1c3e8652f36c0dd02cfe5ff5afaa40357e955a26 100644 (file)
@@ -1587,7 +1587,7 @@ describe('Dropdown', () => {
       triggerDropdown.click()
     })
 
-    it('should not close the dropdown if the user clicks on a text field', done => {
+    it('should not close the dropdown if the user clicks on a text field within dropdown-menu', done => {
       fixtureEl.innerHTML = [
         '<div class="dropdown">',
         '  <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
@@ -1613,7 +1613,7 @@ describe('Dropdown', () => {
       triggerDropdown.click()
     })
 
-    it('should not close the dropdown if the user clicks on a textarea', done => {
+    it('should not close the dropdown if the user clicks on a textarea within dropdown-menu', done => {
       fixtureEl.innerHTML = [
         '<div class="dropdown">',
         '  <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
@@ -1639,6 +1639,32 @@ describe('Dropdown', () => {
       triggerDropdown.click()
     })
 
+    it('should close the dropdown if the user clicks on a text field that is not contained within dropdown-menu', done => {
+      fixtureEl.innerHTML = [
+        '<div class="dropdown">',
+        '  <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+        '  <div class="dropdown-menu">',
+        '  </div>',
+        '</div>',
+        '<input type="text">'
+      ]
+
+      const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+      const input = fixtureEl.querySelector('input')
+
+      triggerDropdown.addEventListener('hidden.bs.dropdown', () => {
+        done()
+      })
+
+      triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+        input.dispatchEvent(createEvent('click', {
+          bubbles: true
+        }))
+      })
+
+      triggerDropdown.click()
+    })
+
     it('should ignore keyboard events for <input>s and <textarea>s within dropdown-menu, except for escape key', done => {
       fixtureEl.innerHTML = [
         '<div class="dropdown">',