diff options
author | GeoSot <geo.sotis@gmail.com> | 2022-09-14 16:24:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-14 16:24:37 +0300 |
commit | 3bd57564140ef3953582a80e8f1084d81bdb5977 (patch) | |
tree | 1c3b3af0e793bffce5226cf6a2fe20f885e807cc /js | |
parent | 4600a2540463b9ea5a3c505de92d1c0252c01fd5 (diff) |
fix: add trick to support tooltip selector usage on dynamic created tooltips that utilize `title` attribute (#36914)
Diffstat (limited to 'js')
-rw-r--r-- | js/src/tooltip.js | 49 | ||||
-rw-r--r-- | js/tests/visual/tooltip.html | 54 |
2 files changed, 58 insertions, 45 deletions
diff --git a/js/src/tooltip.js b/js/src/tooltip.js index e30701efcc..86c6056d82 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -121,6 +121,10 @@ class Tooltip extends BaseComponent { this.tip = null this._setListeners() + + if (!this._config.selector) { + this._fixTitle() + } } // Getters @@ -149,25 +153,12 @@ class Tooltip extends BaseComponent { this._isEnabled = !this._isEnabled } - toggle(event) { + toggle() { if (!this._isEnabled) { return } - if (event) { - const context = this._initializeOnDelegatedTarget(event) - - context._activeTrigger.click = !context._activeTrigger.click - - if (context._isWithActiveTrigger()) { - context._enter() - } else { - context._leave() - } - - return - } - + this._activeTrigger.click = !this._activeTrigger.click if (this._isShown()) { this._leave() return @@ -185,8 +176,8 @@ class Tooltip extends BaseComponent { this.tip.remove() } - if (this._config.originalTitle) { - this._element.setAttribute('title', this._config.originalTitle) + if (this._element.getAttribute('data-bs-original-title')) { + this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')) } this._disposePopper() @@ -375,7 +366,7 @@ class Tooltip extends BaseComponent { } _getTitle() { - return this._resolvePossibleFunction(this._config.title) || this._config.originalTitle + return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title') } // Private @@ -469,7 +460,10 @@ class Tooltip extends BaseComponent { for (const trigger of triggers) { if (trigger === 'click') { - EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => this.toggle(event)) + EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => { + const context = this._initializeOnDelegatedTarget(event) + context.toggle() + }) } else if (trigger !== TRIGGER_MANUAL) { const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : @@ -500,20 +494,10 @@ class Tooltip extends BaseComponent { } EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler) - - if (this._config.selector) { - this._config = { - ...this._config, - trigger: 'manual', - selector: '' - } - } else { - this._fixTitle() - } } _fixTitle() { - const title = this._config.originalTitle + const title = this._element.getAttribute('title') if (!title) { return @@ -523,6 +507,7 @@ class Tooltip extends BaseComponent { this._element.setAttribute('aria-label', title) } + this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility this._element.removeAttribute('title') } @@ -593,7 +578,6 @@ class Tooltip extends BaseComponent { } } - config.originalTitle = this._element.getAttribute('title') || '' if (typeof config.title === 'number') { config.title = config.title.toString() } @@ -614,6 +598,9 @@ class Tooltip extends BaseComponent { } } + config.selector = false + config.trigger = 'manual' + // In the future can be replaced with: // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) // `Object.fromEntries(keysWithDifferentValues)` diff --git a/js/tests/visual/tooltip.html b/js/tests/visual/tooltip.html index 779ac1aaf5..9a65640b44 100644 --- a/js/tests/visual/tooltip.html +++ b/js/tests/visual/tooltip.html @@ -66,42 +66,68 @@ <div id="shadow" class="pt-5"></div> </div> <div id="customContainer"></div> + + <div class="row mt-4 border-top"> + <hr> + <div class="h4">Test Selector triggered tooltips</div> + <div id="wrapperTriggeredBySelector"> + <div class="py-2 selectorButtonsBlock"> + <button type="button" class="btn btn-secondary bs-dynamic-tooltip" title="random title">Using title</button> + <button type="button" class="btn btn-secondary bs-dynamic-tooltip" data-bs-title="random title">Using bs-title</button> + </div> + + </div> + <div class="mt-3"> + <button type="button" class="btn btn-primary" onclick="duplicateButtons()">Duplicate above two buttons</button> + </div> + </div> </div> <script src="../../../dist/js/bootstrap.bundle.js"></script> <script> if (typeof document.body.attachShadow === 'function') { - var shadowRoot = document.getElementById('shadow').attachShadow({ mode: 'open' }) + const shadowRoot = document.getElementById('shadow').attachShadow({ mode: 'open' }) shadowRoot.innerHTML = - '<button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom">' + + '<button id="firstShadowTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom">' + ' Tooltip on top in a shadow dom' + '</button>' + - '<button id="secondTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom with container option">' + + '<button id="secondShadowTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom with container option">' + ' Tooltip on top in a shadow dom' + '</button>' - var firstChildTooltip = new bootstrap.Tooltip(shadowRoot.firstChild) - var secondChildTooltip = new bootstrap.Tooltip(shadowRoot.getElementById('secondTooltip'), { + new bootstrap.Tooltip(shadowRoot.firstChild) + new bootstrap.Tooltip(shadowRoot.getElementById('secondShadowTooltip'), { container: shadowRoot }) } - var tooltipElements = document.querySelectorAll('[data-bs-toggle="tooltip"]') - for (const tooltipEl of tooltipElements) { - new bootstrap.Tooltip(tooltipEl) - } - var tooltipElement = document.getElementById('tooltipElement') - var tooltipElementInstance = new bootstrap.Tooltip(tooltipElement, { - container: document.getElementById('customContainer') + new bootstrap.Tooltip('#tooltipElement', { + container: '#customContainer' }) - var target = document.getElementById('target') - var targetTooltip = new bootstrap.Tooltip(target, { + const targetTooltip = new bootstrap.Tooltip('#target', { placement : 'top', trigger : 'manual' }) targetTooltip.show() + + document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(tooltipEl=> new bootstrap.Tooltip(tooltipEl)) </script> + + <script> + new bootstrap.Tooltip('#wrapperTriggeredBySelector', { + animation: false, + selector: '.bs-dynamic-tooltip' + }) + + function duplicateButtons() { + const buttonsBlock = document.querySelector('.selectorButtonsBlock')// get first + const buttonsBlockClone = buttonsBlock.cloneNode(true) + buttonsBlockClone.innerHTML+= new Date().toLocaleString() + document.querySelector('#wrapperTriggeredBySelector').append(buttonsBlockClone) + } + </script> + </body> </html> |