From bd9084d24900325b0559741c8c227cfdab2f22a0 Mon Sep 17 00:00:00 2001 From: 719media <719media@users.noreply.github.com> Date: Sun, 21 Jan 2018 10:09:23 -0800 Subject: [PATCH] Update dropdown.js to allow referenceElement (#25219) --- docs/4.0/components/dropdowns.md | 38 ++++++++++++++++++++++++++++++++ js/src/dropdown.js | 25 ++++++++++++++------- js/tests/visual/dropdown.html | 28 ++++++++++++++++++++++- 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/docs/4.0/components/dropdowns.md b/docs/4.0/components/dropdowns.md index 670ea59854..b4c70478ef 100644 --- a/docs/4.0/components/dropdowns.md +++ b/docs/4.0/components/dropdowns.md @@ -671,6 +671,38 @@ Add `.disabled` to items in the dropdown to **style them as disabled**. {% endexample %} +## Dropdown options + +Use `data-offset` or `data-reference` to change the location of the dropdown. + +{% example html %} +
+ +
+ + + +
+
+{% endexample %} + ## Usage Via data attributes or JavaScript, the dropdown plugin toggles hidden content (dropdown menus) by toggling the `.show` class on the parent list item. The `data-toggle="dropdown"` attribute is relied on for closing dropdown menus at an application level, so it's a good idea to always use it. @@ -740,6 +772,12 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap 'scrollParent' Overflow constraint boundary of the dropdown menu. Accepts the values of 'viewport', 'window', 'scrollParent', or an HTMLElement reference (JavaScript only). For more information refer to Popper.js's preventOverflow docs. + + reference + string | element + 'toggle' + Reference element of the dropdown menu. Accepts the values of 'toggle', 'parent', or an HTMLElement reference. For more information refer to Popper.js's referenceObject docs. + diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 2ee37f628a..82deaa2205 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -74,13 +74,15 @@ const Dropdown = (($) => { const Default = { offset : 0, flip : true, - boundary : 'scrollParent' + boundary : 'scrollParent', + reference : 'toggle' } const DefaultType = { offset : '(number|string|function)', flip : 'boolean', - boundary : '(string|element)' + boundary : '(string|element)', + reference : '(string|element)' } /** @@ -150,20 +152,27 @@ const Dropdown = (($) => { if (typeof Popper === 'undefined') { throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)') } - let element = this._element - // For dropup with alignment we use the parent as popper container - if ($(parent).hasClass(ClassName.DROPUP)) { - if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) { - element = parent + + let referenceElement = this._element + + if (this._config.reference === 'parent') { + referenceElement = parent + } else if (Util.isElement(this._config.reference)) { + referenceElement = this._config.reference + + // Check if it's jQuery element + if (typeof this._config.reference.jquery !== 'undefined') { + referenceElement = this._config.reference[0] } } + // If boundary is not `scrollParent`, then set position to `static` // to allow the menu to "escape" the scroll parent's boundaries // https://github.com/twbs/bootstrap/issues/24251 if (this._config.boundary !== 'scrollParent') { $(parent).addClass(ClassName.POSITION_STATIC) } - this._popper = new Popper(element, this._menu, this._getPopperConfig()) + this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()) } // If this is a touch-enabled device we add extra diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html index b2e588677c..27a888f040 100644 --- a/js/tests/visual/dropdown.html +++ b/js/tests/visual/dropdown.html @@ -161,8 +161,34 @@ - + +
+
+ +
+
+ +
+
+