i have several buttons and i need a popover for each.
i want it like this:
when my user click on one of them, i want others to be hidden. so only one popover is show
When an icon is clicked and has open the corresponding popover then it has a value that begins with "popover*" called aria-describedby.
So you find this icons and trigger click on them but not on the icon which is clicked now.
$('.icon-info').click(function(){
$(".icon-info[aria-describedby*='popover']").not(this).trigger('click');
});
None of the answers I saw previously had dynamic popovers, so this is what I came up with. As some have pointed out, there are issues with popovers causing problems if they aren't removed from the DOM using .remove()
. I forked an example from the bootstrap website and created this new fiddle. Dynamic popovers are added using the selector: '[rel=popover]'
option. When a popover is about to be shown, I call destroy on all the other popovers, then remove the .popover
content from the page.
$('body').popover({
selector: '[rel=popover]',
trigger: "click"
}).on("show.bs.popover", function(e){
// hide all other popovers
$("[rel=popover]").not(e.target).popover("destroy");
$(".popover").remove();
});
I went for a combinations of approaches I've seen both on this thread and others. My requirements specify that:
Should not require rebinding the popover event
function bindEvents() {
setupPopupBinding();
setupPopupDismissal();
};
function setupPopupBinding() {
$('.addSectionItem').popover({
html: true,
content: function () {
return createDropdowns($(this).data('sectionid'))[0].outerHTML;
},
placement: "right",
trigger: "click focus"
}).on("inserted.bs.popover", function (e) {
//initialize dropdown
setupSelect2();
}).on("hide.bs.popover", function (e) {
$('.select2-container--open').remove();
});
}
function setupPopupDismissal() {
$('body:not(.addSectionItem)').on('click', function (e) {
$('.addSectionItem').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
$('.popover').has(e.target).remove();
}
});
});
}
function createDropdowns(sectionId: number) {
var dropdown = $('<div/>')
.attr('Id', 'sectionPopupWrapper' + sectionId)
.addClass('popupWrapper')
.append($('<select/>').addClass('sectionPopup'))
.append($('<button/>').addClass('btn btn-primary btn-xs')
.attr('data-sectionid', sectionId)
.text('Add'));
return dropdown;
}
Using Bootstrap 3.3.7 I find this solution:
var _popoverLink = $('[data-toggle="popover"]');
_popoverLink.on('click', function(){
_popoverLink.popover('destroy').popover({container: 'body'});
$(this).popover('show');
});
regards.
You are taking this too seriously, just close every opened popover before triggering the new one to be opened:
// Hide any active popover first
$(".popover").each(function () {
var $this = $(this);
$this.popover('hide');
});
//Now Execute your new popover
$('.btn').popover({
html: true,
content: mycontent,
trigger: 'manual'
}).click(function (e) {
$(this).popover('toggle');
e.stopPropagation();
});
I was having some difficulty using any of the answers posted to solve this issue using bootstrap v3. After some searching I found my primary issue was not setting the proper popover trigger. It should be set as 'manual' as listed in the op's question.
The next step was very simple and gives some better behavior than the solutions I see in the other answers so I thought I would share.
$('html').on('click', function(e) {
if($(e.target).hasClass('btn')) {
$(e.target).popover('toggle');
}
if(!$(e.target).parent().hasClass('popover')) {
$('.popover').prev('.btn').not(e.target).popover('toggle');
}
});
This solution gives you the ability to dismiss the popover upon clicking anywhere else on the page including another popover link but allows you to click on the popover itself without dismissing it so that the popover can be accessed by the user for things like copy pasting text.
Hope this helps someone, here is a working fiddle. https://jsfiddle.net/hL0pvaty/
p.s. - I am only using the .btn class as the selector in my example because it is used in the op's question. I would recommend using something less generic.