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 | 26 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 8 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**. </div> {% endexample %} +## Dropdown options + +Use `data-offset` or `data-reference` to change the location of the dropdown. + +{% example html %} +<div class="d-flex"> + <div class="dropdown mr-1"> + <button type="button" class="btn btn-secondary dropdown-toggle" id="dropdownMenuOffset" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-offset="10,20"> + Offset + </button> + <div class="dropdown-menu" aria-labelledby="dropdownMenuOffset"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + </div> + </div> + <div class="btn-group"> + <button type="button" class="btn btn-secondary">Reference</button> + <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" id="dropdownMenuReference" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent"> + <span class="sr-only">Toggle Dropdown</span> + </button> + <div class="dropdown-menu" aria-labelledby="dropdownMenuReference"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="#">Separated link</a> + </div> + </div> +</div> +{% 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 <td>'scrollParent'</td> <td>Overflow constraint boundary of the dropdown menu. Accepts the values of <code>'viewport'</code>, <code>'window'</code>, <code>'scrollParent'</code>, or an HTMLElement reference (JavaScript only). For more information refer to Popper.js's <a href="https://popper.js.org/popper-documentation.html#modifiers..preventOverflow.boundariesElement">preventOverflow docs</a>.</td> </tr> + <tr> + <td>reference</td> + <td>string | element</td> + <td>'toggle'</td> + <td>Reference element of the dropdown menu. Accepts the values of <code>'toggle'</code>, <code>'parent'</code>, or an HTMLElement reference. For more information refer to Popper.js's <a href="https://popper.js.org/popper-documentation.html#referenceObject">referenceObject docs</a>.</td> + </tr> </tbody> </table> 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 @@ </div> </div> </div> + </div> + <div class="row"> + <div class="col-sm-12 mt-4"> + <div class="btn-group dropdown"> + <button type="button" class="btn btn-secondary" data-offset="10,20">Dropdown offset</button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + </div> + </div> + </div> + <div class="col-sm-12 mt-4"> + <div class="btn-group dropdown"> + <button type="button" class="btn btn-secondary">Dropdown reference</button> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent"> + <span class="sr-only">Dropdown split</span> + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + </div> + </div> + </div> </div> + </div> <script src="../../../assets/js/vendor/jquery-slim.min.js"></script> -- GitLab