diff options
| author | GeoSot <[email protected]> | 2021-08-10 17:55:34 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-08-10 17:55:34 +0300 |
| commit | 1e5e65567049cc5a7521530fbc1149f8c35b96f9 (patch) | |
| tree | 7290e5ee700ea0322bd314130a4de867157b3167 | |
| parent | 418fe8113ec78e3b7251322560cd2d4a5bc6b71e (diff) | |
| download | bootstrap-1e5e65567049cc5a7521530fbc1149f8c35b96f9.tar.xz bootstrap-1e5e65567049cc5a7521530fbc1149f8c35b96f9.zip | |
Fix modal when is triggered by `bs-toggle`, to hide other open instances (#34701)
| -rw-r--r-- | js/src/modal.js | 7 | ||||
| -rw-r--r-- | js/tests/unit/modal.spec.js | 23 | ||||
| -rw-r--r-- | site/content/docs/5.1/components/modal.md | 2 |
3 files changed, 31 insertions, 1 deletions
diff --git a/js/src/modal.js b/js/src/modal.js index 8453dbc9d..7d44c31e8 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -63,6 +63,7 @@ const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' const CLASS_NAME_STATIC = 'modal-static' +const OPEN_SELECTOR = '.modal.show' const SELECTOR_DIALOG = '.modal-dialog' const SELECTOR_MODAL_BODY = '.modal-body' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]' @@ -411,6 +412,12 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) }) + // avoid conflict when clicking moddal toggler while another one is open + const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR) + if (allReadyOpen) { + Modal.getInstance(allReadyOpen).hide() + } + const data = Modal.getOrCreateInstance(target) data.toggle(this) diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index 562b32561..a65ed4afa 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -978,6 +978,29 @@ describe('Modal', () => { trigger.click() }) + + it('should call hide first, if another modal is open', done => { + fixtureEl.innerHTML = [ + '<button data-bs-toggle="modal" data-bs-target="#modal2"></button>', + '<div id="modal1" class="modal fade"><div class="modal-dialog"></div></div>', + '<div id="modal2" class="modal"><div class="modal-dialog"></div></div>' + ].join('') + + const trigger2 = fixtureEl.querySelector('button') + const modalEl1 = document.querySelector('#modal1') + const modalEl2 = document.querySelector('#modal2') + const modal1 = new Modal(modalEl1) + + modalEl1.addEventListener('shown.bs.modal', () => { + trigger2.click() + }) + modalEl1.addEventListener('hidden.bs.modal', () => { + expect(Modal.getInstance(modalEl2)).not.toBeNull() + expect(modalEl2.classList.contains('show')).toBeTrue() + done() + }) + modal1.show() + }) }) describe('jQueryInterface', () => { diff --git a/site/content/docs/5.1/components/modal.md b/site/content/docs/5.1/components/modal.md index 7b8902820..118dc842f 100644 --- a/site/content/docs/5.1/components/modal.md +++ b/site/content/docs/5.1/components/modal.md @@ -528,7 +528,7 @@ Toggle between multiple modals with some clever placement of the `data-bs-target Hide this modal and show the first with the button below. </div> <div class="modal-footer"> - <button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal" data-bs-dismiss="modal">Back to first</button> + <button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal">Back to first</button> </div> </div> </div> |
