]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
modal: change `data-dismiss` so that it can be outside of a modal using `bs-target...
authorGeoSot <geo.sotis@gmail.com>
Mon, 19 Jul 2021 13:56:05 +0000 (16:56 +0300)
committerGitHub <noreply@github.com>
Mon, 19 Jul 2021 13:56:05 +0000 (16:56 +0300)
* change data-dismiss, so can be outside modal, using a bs-target

* Update site/content/docs/5.0/components/modal.md

Co-authored-by: Gaƫl Poupard <ffoodd@users.noreply.github.com>
js/src/modal.js
js/tests/unit/modal.spec.js
site/content/docs/5.0/components/modal.md

index 8dac75265cc57995e55331338c9b980513ce7c1b..0e8346d6f3f0844ebdd771c68092f6c46ed7d90b 100644 (file)
@@ -62,6 +62,7 @@ const CLASS_NAME_FADE = 'fade'
 const CLASS_NAME_SHOW = 'show'
 const CLASS_NAME_STATIC = 'modal-static'
 
+const SELECTOR = '.modal'
 const SELECTOR_DIALOG = '.modal-dialog'
 const SELECTOR_MODAL_BODY = '.modal-body'
 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'
@@ -130,8 +131,6 @@ class Modal extends BaseComponent {
     this._setEscapeEvent()
     this._setResizeEvent()
 
-    EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, event => this.hide(event))
-
     EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
       EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
         if (event.target === this._element) {
@@ -436,6 +435,13 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
   data.toggle(this)
 })
 
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_DISMISS, function (event) {
+  const target = getElementFromSelector(this) || this.closest(SELECTOR)
+  const modal = Modal.getOrCreateInstance(target)
+
+  modal.hide(event)
+})
+
 /**
  * ------------------------------------------------------------------------
  * jQuery
index e6ef555e7007a8984fa2374ff337d41ce015e978..86b366001f6c29094a96a92d07a78708a76457d6 100644 (file)
@@ -249,7 +249,7 @@ describe('Modal', () => {
       modal.show()
     })
 
-    it('should close modal when a click occurred on data-bs-dismiss="modal"', done => {
+    it('should close modal when a click occurred on data-bs-dismiss="modal" inside modal', done => {
       fixtureEl.innerHTML = [
         '<div class="modal fade">',
         '  <div class="modal-dialog">',
@@ -278,6 +278,33 @@ describe('Modal', () => {
       modal.show()
     })
 
+    it('should close modal when a click occurred on a data-bs-dismiss="modal" with "bs-target" outside of modal element', done => {
+      fixtureEl.innerHTML = [
+        '<button type="button" data-bs-dismiss="modal" data-bs-target="#modal1"></button>',
+        '<div id="modal1" class="modal fade">',
+        '  <div class="modal-dialog">',
+        '  </div>',
+        '</div>'
+      ].join('')
+
+      const modalEl = fixtureEl.querySelector('.modal')
+      const btnClose = fixtureEl.querySelector('[data-bs-dismiss="modal"]')
+      const modal = new Modal(modalEl)
+
+      spyOn(modal, 'hide').and.callThrough()
+
+      modalEl.addEventListener('shown.bs.modal', () => {
+        btnClose.click()
+      })
+
+      modalEl.addEventListener('hidden.bs.modal', () => {
+        expect(modal.hide).toHaveBeenCalled()
+        done()
+      })
+
+      modal.show()
+    })
+
     it('should set .modal\'s scroll top to 0', done => {
       fixtureEl.innerHTML = [
         '<div class="modal fade">',
index e6a838aac284c3e10a3df3015f2c9be696143d0f..7ba55b3b509ac5790e29ce86ac2ac94e692c91f1 100644 (file)
@@ -831,11 +831,29 @@ The modal plugin toggles your hidden content on demand, via data attributes or J
 
 ### Via data attributes
 
+#### Toggle
+
 Activate a modal without writing JavaScript. Set `data-bs-toggle="modal"` on a controller element, like a button, along with a `data-bs-target="#foo"` or `href="#foo"` to target a specific modal to toggle.
 
 ```html
 <button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Launch modal</button>
 ```
+#### Dismiss
+
+Dismissal can be achieved with `data` attributes on a button **within the modal** as demonstrated below:
+
+```html
+<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+```
+
+or on a button **outside the modal** using the `data-bs-target` as demonstrated below:
+
+```html
+<button type="button" class="btn-close" data-bs-dismiss="modal" data-bs-target="#my-modal" aria-label="Close"></button>
+```
+{{< callout warning >}}
+While both ways to dismiss a modal are supported, keep in mind that dismissing from outside a modal does not match [the WAI-ARIA modal dialog design pattern](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal). Do this at your own risk.
+{{< /callout >}}
 
 ### Via JavaScript