diff --git a/docs/4.0/components/collapse.md b/docs/4.0/components/collapse.md index c77d436fb07c..70e38649aac5 100644 --- a/docs/4.0/components/collapse.md +++ b/docs/4.0/components/collapse.md @@ -226,6 +226,10 @@ Shows a collapsible element. **Returns to the caller before the collapsible elem Hides a collapsible element. **Returns to the caller before the collapsible element has actually been hidden** (i.e. before the `hidden.bs.collapse` event occurs). +#### `.collapse('update')` + +Update a collapsible element if it changed during its lifetime. + ### Events Bootstrap's collapse class exposes a few events for hooking into collapse functionality. diff --git a/js/src/collapse.js b/js/src/collapse.js index 112b2c3ad408..452e11759301 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -87,7 +87,8 @@ const Collapse = (($) => { } } - this._parent = this._config.parent ? this._getParent() : null + this._parent = this._config.parent ? this._getParent() : null + this._showClass = this._getShowClass() if (!this._config.parent) { this._addAriaAndCollapsedClass(this._element, this._triggerArray) @@ -113,7 +114,7 @@ const Collapse = (($) => { // public toggle() { - if ($(this._element).hasClass(ClassName.SHOW) || $(this._element).hasClass(ClassName.FLEXSHOW)) { + if ($(this._element).hasClass(this._showClass)) { this.hide() } else { this.show() @@ -121,9 +122,8 @@ const Collapse = (($) => { } show() { - const showClass = this._getShowClass() if (this._isTransitioning || - $(this._element).hasClass(showClass)) { + $(this._element).hasClass(this._showClass)) { return } @@ -177,7 +177,7 @@ const Collapse = (($) => { $(this._element) .removeClass(ClassName.COLLAPSING) .addClass(ClassName.COLLAPSE) - .addClass(showClass) + .addClass(this._showClass) this._element.style[dimension] = '' @@ -202,9 +202,8 @@ const Collapse = (($) => { } hide() { - const showClass = this._getShowClass() if (this._isTransitioning || - !$(this._element).hasClass(showClass)) { + !$(this._element).hasClass(this._showClass)) { return } @@ -214,8 +213,7 @@ const Collapse = (($) => { return } - const dimension = this._getDimension() - + const dimension = this._getDimension() this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px` Util.reflow(this._element) @@ -223,7 +221,7 @@ const Collapse = (($) => { $(this._element) .addClass(ClassName.COLLAPSING) .removeClass(ClassName.COLLAPSE) - .removeClass(showClass) + .removeClass(this._showClass) if (this._triggerArray.length) { for (let i = 0; i < this._triggerArray.length; i++) { @@ -265,6 +263,16 @@ const Collapse = (($) => { this._isTransitioning = isTransitioning } + update() { + if ($(this._element).hasClass(this._showClass)) { + $(this._element).removeClass(this._showClass) + this._showClass = this._getShowClass() + $(this._element).addClass(this._showClass) + } else { + this._showClass = this._getShowClass() + } + } + dispose() { $.removeData(this._element, DATA_KEY) @@ -319,15 +327,28 @@ const Collapse = (($) => { _getShowClass() { const tabClass = this._element.classList - let useFlex = $(this._element).css('display') === 'flex' + + // Detect flex for inline style + let useFlex = $(this._element).css('display').indexOf('flex') !== -1 + + // Create a wrapper to hide our flex detection + const $tmpWrapper = $('
') + $tmpWrapper.insertAfter($(this._element)) + + const $tmpElem = $('
') + $tmpWrapper.append($tmpElem) + // Detect flex in used classes for (let i = 0; i < tabClass.length; i++) { - const tmpDisplay = $('
').addClass(tabClass[i]).css('display') - if (tmpDisplay === 'flex') { + $tmpElem.addClass(tabClass[i]) + const tmpDisplay = $tmpElem.css('display') + $tmpElem.removeClass(tabClass[i]) + if (tmpDisplay.indexOf('flex') !== -1) { useFlex = true break } } + $tmpWrapper.remove() return !useFlex ? ClassName.SHOW : ClassName.FLEXSHOW } diff --git a/scss/_transitions.scss b/scss/_transitions.scss index 033942f8e0e0..14007b8e02dd 100644 --- a/scss/_transitions.scss +++ b/scss/_transitions.scss @@ -18,13 +18,15 @@ } tr { - &.collapse.show { + &.collapse.show, + &.collapse.flexshow { display: table-row; } } tbody { - &.collapse.show { + &.collapse.show, + &.collapse.flexshow { display: table-row-group; } }