Reputation: 3291
I have a scenario with Bootstrap Popovers (version 2.3 although I can recreate the issue in 3 as well) where I have multiple popovers on the page and I want to be able to close any open popovers when a new one is opened.
The method I have (taken from here) to close open popovers works fine until I initialize my popovers using the selector
option which delegates the popover objects.
Here's the JS:
// Works if popovers are instantiated this way
//$("[data-toggle=popover]").popover();
// Doesn't work if popovers are instantiated this way
var options = { selector: '[data-toggle=popover]' };
$(".container").popover(options)
$("[data-toggle=popover]").click(function() {
$("[data-toggle=popover]").not(this).popover('hide');
});
And the HTML:
<div class="container">
<a href="#" class="btn btn-large btn-danger" data-toggle="popover" title="" data-placement="bottom" data-content="And here's some amazing content. It's very engaging. right?" data-original-title="Popover Title">Click to see my popover.</a>
<a href="#" class="btn btn-large btn-danger" data-toggle="popover" title="" data-placement="bottom" data-content="And here's some amazing content. It's very engaging. right?" data-original-title="Popover Title">Click to see my popover.</a>
</div>
I've spent some time digging through the source code and I see what the issue might be, but I'm not sure how to work around this. Has anyone made something like this work before?
Update:
This does work - $("[data-toggle=popover]").filter(this).popover('show');
- My only concern is this block of code from the popover library:
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
if (!data && option == 'destroy') return
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
The line
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
adds a data attribute to .container
when the popover is init'ed initially using the selector
option, but then when
$("[data-toggle=popover]").not(this).popover('hide');
is called it loops through each element that matches the $("[data-toggle=popover]")
selector and re-inits a popover on each element it finds, ignoring the fact that a popover object was already added to the parent container and set to work via delegation using the selector option. Is there any way to avoid this?
Upvotes: 0
Views: 580
Reputation: 2537
The easiest and - in my opinion - the best way to do that, is to use <button>
instead of <a>
and then use the focus
trigger.
var options = { selector: '[data-toggle=popover]', trigger: 'focus' };
$(".container").popover(options);
<div class="container">
<button class="btn btn-large btn-danger" data-toggle="popover" title="" data-placement="bottom" data-content="And here's some amazing content. It's very engaging. right?" data-original-title="Popover Title">Click to see my popover.</button>
<button class="btn btn-large btn-danger" data-toggle="popover" title="" data-placement="bottom" data-content="And here's some amazing content. It's very engaging. right?" data-original-title="Popover Title">Click to see my popover.</button>
</div>
Here is a bootply
If you don't want/can't change the anchors, you can try that:
var options = { selector: '[data-toggle=popover]' };
$("body").popover(options)
$("[data-toggle=popover]").on('shown.bs.popover', function(e) {
$(this).addClass('shown');
});
$("body").on('click', '[data-toggle=popover]', function(e) {
$('.shown').not(this).popover('hide').removeClass('shown');
});
Here is another bootply.
Upvotes: 2
Reputation: 25957
Your Javascript hides the other popovers just fine... but you forgot to open the new one!
var options = { selector: '[data-toggle=popover]' };
$(".container").popover(options);
$("[data-toggle=popover]").click(function() {
$("[data-toggle=popover]").not(this).popover('hide');
$("[data-toggle=popover]").this.popover('show');
});
Disclosure: I actually don't know what I'm doing, but when I checked the Bootstrap documentation and ran this in Bootply it appears to create the behavior you are looking for.
Upvotes: 0