Reputation: 892
I am trying to change the trigger of a Bootstrap popover using an html switch, I have some basic jQuery set up but each time I flip the switch each but popover responds differently.
I set up each popover, then put it into a function that I can call each time I change the trigger. I have the trigger set as a global variable that is changed by the function that runs on the html switch change.
Here is my jquery, the html is located at the codepen link.
jQuery(document).ready(function ($) {
var click_funct = 'hover';
$(".nrl-hint").contents().find(":checkbox").bind('change', function(){
var check_checked = $('#nrl-hint').is(":checked");
if (check_checked) {
console.log("Check ran");
click_funct = 'click';
$("[data-toggle=popover]").popover('destroy');
$("[data-toggle=popover_2]").popover('destroy');
$("[data-toggle=popover_3]").popover('destroy');
$("[data-toggle=popover_4]").popover('destroy');
$("[data-toggle=popover_5]").popover('destroy');
box_funct(click_funct);
}
else {
console.log('Check ran x2');
click_funct = 'hover';
$("[data-toggle=popover]").popover('destroy');
$("[data-toggle=popover_2]").popover('destroy');
$("[data-toggle=popover_3]").popover('destroy');
$("[data-toggle=popover_4]").popover('destroy');
$("[data-toggle=popover_5]").popover('destroy');
box_funct(click_funct);
}
});
function box_funct(click_funct) {
$(".ow-button-hover").attr("href", "javascript:void(0)");
$('.ow-button-hover').popover({
html : true,
trigger : 'click',
placement: "top",
content: function() {
return $('#contact_form_nrl').html();
},
template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
$('[data-toggle=popover]').popover({
html : true,
trigger : click_funct,
content: function() {
return $('#popover_content_wrapper').html();
},
template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
$('[data-toggle=popover_2]').popover({
html : true,
trigger : click_funct,
content: function() {
return $('#popover_content_wrapper_2').html();
},
template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
$('[data-toggle=popover_3]').popover({
html : true,
trigger : click_funct,
placement : 'left',
content: function() {
return $('#popover_content_wrapper_3').html();
},
template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
$('[data-toggle=popover_4]').popover({
html : true,
trigger : click_funct,
placement : 'right',
content: function() {
return $('#popover_content_wrapper_4').html();
},
template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
$('[data-toggle=popover_5]').popover({
html : true,
trigger : click_funct,
placement : 'right',
content: function() {
return $('#popover_content_wrapper_5').html();
},
template: '<div class="popover nrl-popover-2"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
}
box_funct(click_funct);
});
Here is a codepen link to demonstrate. https://codepen.io/RobertCC/pen/Qqzwgd
I greatly appreciate any help! I know I am probably missing something.
Upvotes: 3
Views: 8175
Reputation: 6967
Based on my understanding of what you're wanting to do I think we can reduce the amount of code you're using considerably. Bootstrap's Popover already supports triggers like click
and hover
so it's just a matter of re-initializing the Popover with the new trigger.
$("#pHover, #pClick").click(function() {
var popTrigger = $(this).data("trigger");
$('[data-toggle="popover"]').popover('dispose');
$('[data-toggle="popover"]').popover({ trigger: popTrigger });
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<div class="btn-group">
<button class="btn btn-info" id="pHover" data-trigger="hover">Hover</button>
<button class="btn btn-danger" id="pClick" data-trigger="click">Click</button>
</div>
<hr />
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="top" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on top</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="right" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on right</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on bottom</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on left</button>
Now for the purposes of this example you'll notice that the default state is that the Popover simply doesn't initialize. Clicking on "Hover" or "Click" applies the value of data-trigger
to the popover initialization.
Note also that we have to destroy the popover before we re-initialize with the new trigger value (hence popover('dispose')
.
My example utilizes the latest version of Bootstrap (4.x) but this should work with version 3 as well, with some considerations for how popovers have migrated (3.x uses destroy
and 4.x uses dispose
).
One additional note worth considering; you can call a Popover using the data-trigger
attribute alongside data-toggle="popover"
. It might be possible to figure out a way to change the value of data-trigger
here and re-initialize the popover that way, too.
Edit: For Bootstrap 3.x users wrap the popover create function in a setTimeout(); function like this.
$("#pHover, #pClick").click(function() {
var popTrigger = $(this).data("trigger");
$('[data-toggle="popover"]').popover('dispose');
setTimeout(function () {
$('[data-toggle="popover"]').popover({ trigger: popTrigger });
}, 200);
});
It turns out .popover('destroy')
is asynchronous, and immediate initialization of another popover fails, while the previous one is being removed.
Upvotes: 2