mirror of
https://github.com/twbs/bootstrap.git
synced 2022-11-09 12:25:43 -05:00
fix: add trick to support tooltip selector usage on dynamic created tooltips that utilize title
attribute (#36914)
This commit is contained in:
parent
4600a25404
commit
3bd5756414
2 changed files with 58 additions and 45 deletions
|
@ -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)`
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue