Reputation: 467
I have the following setup for a bootstrap popover. The popover appears when the page is loaded and if I click on the popover, it disappears. What I would really like though is for it to disappear if I click outside the popover or even better on the next click. Any ideas on how to make this work?
$('div').on('hide.bs.popover', function (e) {
e.preventDefault();
});
$(document).ready(function() {
$("div").popover("show");
});
$('body').on('click', '.popover', function () {
$(this).hide();
});
<div class="dropdown pull-right" data-toggle="popover" data-placement="left" data-content="Main menu" style="right: -2px; top: 3px;">
<a href="#" class="glyphicon glyphicon-th dropdown-toggle" data-toggle="dropdown" style="color: #317EAC; text-decoration: none !important; font-size: 22px;"></a>
</div>
Upvotes: 1
Views: 6802
Reputation: 1100
This is for non jquery version (bootstrap 5+), the trick here is to take advantage of html tabindex attribute so that we can listen to focusout event
let pCustomClass = "my_popover"; // this is very important as we will use it to track our parent popover class
let trigger = document.querySelector(".popover_trigger")
let _popover = new bootstrap.Popover(trigger, {
fallbackPlacements: ["left", "top"],
trigger:'click',
customClass: pCustomClass, // dont forget the custom class
})
// after the popover is shown, lets add a tabindex and then focus the parent element
trigger.addEventListener('shown.bs.popover', () => {
let el = document.querySelector("."+pCustomClass)
if(!el) return;
// set the tabindex to -1, -1 is required as we do not need
// keyboard tab feature, we want only the focus
el.setAttribute("tabindex", -1)
el.addEventListener("focusout", async (e) => {
if(!el.contains( e.relatedTarget)){
// hide the popover when focused out
_popover.hide()
}
})
// finally, focus the parent .popover element
el.focus()
})
//once closed, remove the focus event
trigger.addEventListener('hide.bs.popover', () => {
let el = document.querySelector("."+pCustomClass)
if(!el) return;
el.removeEventListener("focusout", ()=>{})
})
Upvotes: 2
Reputation: 467
Found the solution for this:
$(document).ready(function() {
$("div").popover("show");
});
$('body').on('click', function (e) {
if ($(e.target).data('toggle') !== 'popover'
&& $(e.target).parents('.popover.in').length === 0) {
$('[data-toggle="popover"]').popover('hide');
}
});
Upvotes: 2
Reputation: 299
As per documentation:
Use the focus trigger to dismiss popovers on the next click that the user makes.
So use data-trigger="focus"
Specific markup required for dismiss-on-next-click For proper cross-browser and cross-platform behavior, you must use the tag, not the tag, and you also must include the role="button" and tabindex attributes.
<a tabindex="0" class="btn btn-lg btn-danger" role="button" data-toggle="popover" data-trigger="focus" title="Dismissible popover" data-content="And here's some amazing content. It's very engaging. Right?">Dismissible popover</a>
Upvotes: 2
Reputation: 4173
$('body').on('click', function (e) {
$('[data-toggle=popover]').each(function () {
// hide any open popovers when the anywhere else in the body is clicked
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
Upvotes: 1