]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Add `show` and `hide` methods to dropdown (#27370)
authorgalczo5 <kamil.galek@gmail.com>
Sat, 20 Oct 2018 11:27:51 +0000 (13:27 +0200)
committerXhmikosR <xhmikosr@gmail.com>
Sat, 20 Oct 2018 11:27:51 +0000 (14:27 +0300)
js/src/dropdown.js
js/tests/unit/dropdown.js
site/docs/4.1/components/dropdowns.md

index a7a77cb3b6ca5a8fc4dd0ffd41ae106d1a20218f..e52c51e4db759fbc49e937e3916a7dc8782f6c74 100644 (file)
@@ -194,6 +194,52 @@ class Dropdown {
       .trigger($.Event(Event.SHOWN, relatedTarget))
   }
 
+  show() {
+    if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || $(this._menu).hasClass(ClassName.SHOW)) {
+      return
+    }
+
+    const relatedTarget = {
+      relatedTarget: this._element
+    }
+    const showEvent = $.Event(Event.SHOW, relatedTarget)
+
+    const parent = Dropdown._getParentFromElement(this._element)
+    $(parent).trigger(showEvent)
+
+    if (showEvent.isDefaultPrevented()) {
+      return
+    }
+
+    $(this._menu).toggleClass(ClassName.SHOW)
+    $(parent)
+      .toggleClass(ClassName.SHOW)
+      .trigger($.Event(Event.SHOWN, relatedTarget))
+  }
+
+  hide() {
+    if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || !$(this._menu).hasClass(ClassName.SHOW)) {
+      return
+    }
+
+    const relatedTarget = {
+      relatedTarget: this._element
+    }
+    const hideEvent = $.Event(Event.HIDE, relatedTarget)
+
+    const parent = Dropdown._getParentFromElement(this._element)
+    $(parent).trigger(hideEvent)
+
+    if (hideEvent.isDefaultPrevented()) {
+      return
+    }
+
+    $(this._menu).toggleClass(ClassName.SHOW)
+    $(parent)
+      .toggleClass(ClassName.SHOW)
+      .trigger($.Event(Event.HIDDEN, relatedTarget))
+  }
+
   dispose() {
     $.removeData(this._element, DATA_KEY)
     $(this._element).off(EVENT_KEY)
index 40489c5f2c3f3445db02663e5249fda5463159ea..fd9b7f9629588c8286d411debd186c158c8c2f7b 100644 (file)
@@ -1097,4 +1097,268 @@ $(function () {
     assert.ok(dropdown._menu === null)
     assert.ok(dropdown._element === null)
   })
+
+  QUnit.test('should show dropdown', function (assert) {
+    assert.expect(2)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    var done = assert.async()
+
+    $dropdown
+      .parent('.dropdown')
+      .on('show.bs.dropdown', function () {
+        assert.ok(true, 'show was fired')
+      })
+      .on('shown.bs.dropdown', function () {
+        assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+        done()
+      })
+
+    dropdown.show()
+  })
+
+  QUnit.test('should hide dropdown', function (assert) {
+    assert.expect(2)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    var done = assert.async()
+    $dropdown.trigger('click')
+
+    $dropdown
+      .parent('.dropdown')
+      .on('hide.bs.dropdown', function () {
+        assert.ok(true, 'hide was fired')
+      })
+      .on('hidden.bs.dropdown', function () {
+        assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is hidden')
+        done()
+      })
+
+    dropdown.hide()
+  })
+
+  QUnit.test('should not hide dropdown', function (assert) {
+    assert.expect(1)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    $dropdown.trigger('click')
+    dropdown.show()
+
+    assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is still shown')
+  })
+
+  QUnit.test('should not show dropdown', function (assert) {
+    assert.expect(1)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    dropdown.hide()
+    assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is still hidden')
+  })
+
+  QUnit.test('should show dropdown', function (assert) {
+    assert.expect(2)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    var done = assert.async()
+
+    $dropdown
+      .parent('.dropdown')
+      .on('show.bs.dropdown', function () {
+        assert.ok(true, 'show was fired')
+      })
+      .on('shown.bs.dropdown', function () {
+        assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+        done()
+      })
+
+    dropdown.show()
+  })
+
+  QUnit.test('should prevent default event on show method call', function (assert) {
+    assert.expect(1)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    var done = assert.async()
+
+    $dropdown
+      .parent('.dropdown')
+      .on('show.bs.dropdown', function (event) {
+        event.preventDefault()
+        done()
+      })
+
+    dropdown.show()
+    assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is hidden')
+  })
+
+  QUnit.test('should prevent default event on hide method call', function (assert) {
+    assert.expect(1)
+
+    var dropdownHTML =
+      '<div class="dropdown">' +
+      '  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
+      '  <div class="dropdown-menu">' +
+      '    <a class="dropdown-item" href="#">Another link</a>' +
+      '  </div>' +
+      '</div>'
+
+    var $dropdown = $(dropdownHTML)
+      .appendTo('#qunit-fixture')
+      .find('[data-toggle="dropdown"]')
+      .bootstrapDropdown()
+
+    var dropdown = $dropdown.data('bs.dropdown')
+    var done = assert.async()
+    $dropdown.trigger('click')
+
+    $dropdown
+      .parent('.dropdown')
+      .on('hide.bs.dropdown', function (event) {
+        event.preventDefault()
+        done()
+      })
+
+    dropdown.hide()
+    assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+  })
+
+  QUnit.test('should not open dropdown via show method if target is disabled via attribute', function (assert) {
+    assert.expect(1)
+    var dropdownHTML =
+        '<div class="dropdown">' +
+        '  <button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>' +
+        '  <div class="dropdown-menu">' +
+        '    <a class="dropdown-item" href="#">Another link</a>' +
+        '  </div>' +
+        '</div>'
+    $(dropdownHTML).appendTo('#qunit-fixture')
+    var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+    $dropdown.show()
+    assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+  })
+
+  QUnit.test('should not open dropdown via show method if target is disabled via class', function (assert) {
+    assert.expect(1)
+    var dropdownHTML =
+        '<div class="dropdown">' +
+        '  <button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>' +
+        '  <div class="dropdown-menu">' +
+        '    <a class="dropdown-item" href="#">Another link</a>' +
+        '  </div>' +
+        '</div>'
+
+    $(dropdownHTML).appendTo('#qunit-fixture')
+    var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+    $dropdown.show()
+    assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+  })
+
+  QUnit.test('should not hide dropdown via hide method if target is disabled via attribute', function (assert) {
+    assert.expect(1)
+    var dropdownHTML =
+        '<div class="dropdown show">' +
+        '  <button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>' +
+        '  <div class="dropdown-menu">' +
+        '    <a class="dropdown-item" href="#">Another link</a>' +
+        '  </div>' +
+        '</div>'
+    $(dropdownHTML).appendTo('#qunit-fixture')
+    var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+    $dropdown.hide()
+    assert.ok($dropdown.parent('.dropdown').hasClass('show'))
+  })
+
+  QUnit.test('should not hide dropdown via hide method if target is disabled via class', function (assert) {
+    assert.expect(1)
+    var dropdownHTML =
+        '<div class="dropdown show">' +
+        '  <button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>' +
+        '  <div class="dropdown-menu">' +
+        '    <a class="dropdown-item" href="#">Another link</a>' +
+        '  </div>' +
+        '</div>'
+
+    $(dropdownHTML).appendTo('#qunit-fixture')
+    var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+    $dropdown.hide()
+    assert.ok($dropdown.parent('.dropdown').hasClass('show'))
+  })
 })
index c9daf5518622c2fa01da6dce55996de9e169af90..ab61390d4e4c0c0eaf889cd1b20b245cae2c25c8 100644 (file)
@@ -839,6 +839,8 @@ Note when `boundary` is set to any value other than `'scrollParent'`, the style
 | Method | Description |
 | --- | --- |
 | `$().dropdown('toggle')` | Toggles the dropdown menu of a given navbar or tabbed navigation. |
+| `$().dropdown('show')` | Shows the dropdown menu of a given navbar or tabbed navigation. |
+| `$().dropdown('hide')` | Hides the dropdown menu of a given navbar or tabbed navigation. |
 | `$().dropdown('update')` | Updates the position of an element's dropdown. |
 | `$().dropdown('dispose')` | Destroys an element's dropdown. |