I am trying to use a BS popover, my first time. I need to use the same popover for multiple elements so content and title will be dynamic. I googled and viewed a bunch of suggestions and still can't get this to work. I can see when element (a Fontawsome icon) is clicked, the appropriate function is called to fetch the title and content, but having problems with the popover.
<label>
Some Text
<span>
<i
class='fas fa-question-circle descPopover'
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc')"
></i>
</span>
</label>
<label>
Some Other Text
<span>
<i
class='fas fa-question-circle descPopover'
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc')"
></i>
</span>
</label>
function showDescr(code) {
var descr = 'some description fecthed from an array';
var heading = 'some title fecthed from an array';
$('.descPopover').data("title", heading);
$('.descPopover').data("content", descr);
$('.descPopover').popover('show');
}
$(document).ready(function () {
$('[data-bs-toggle="popover"]').popover();
$('.descPopover').on('show.bs.popover', function (e) {
var popover = $(this);
var content = popover.data('content');
var title = popover.data('title');
$('#descContainer').html(content);
});
// ...
});
When the question mark icon is clicked, it shows a popover, with two titles, presumably one for each label, one above the other, ("Click for more info") and the text "Loading ..." and no way to close it.
I put a breakpoing on showDesc() and can see it gets called but on('show.bs.popover') doesn't.
Even though it's not quite clear, what your final goal is, here's a simple setup that will make both popovers work with the dynamic content:
<label>
Some Text
<span>
<i
class='fas fa-question-circle descPopover'
tabindex="0"
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc', this)"
></i>
</span>
</label>
<label>
Some Other Text
<span>
<i
class='fas fa-question-circle descPopover'
tabindex="0"
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc', this)"
></i>
</span>
</label>
function showDescr(code, el) {
var descr = 'some description fecthed from an array';
var heading = 'some title fecthed from an array';
$(el).attr("data-bs-title", heading);
$(el).attr("data-bs-content", descr);
$(el).popover('toggle');
}
$("[data-bs-trigger='focus']").on("blur", e =>{
$(e.target).popover("hide");
})
function showDescr(code, el) {
var descr = 'some description fecthed from an array ' + Math.random().toFixed(2);
var heading = 'some title fecthed from an array ' + Math.random().toFixed(2);
$(el).attr("data-bs-title", heading);
$(el).attr("data-bs-content", descr);
$(el).popover('toggle');
}
$("[data-bs-trigger='focus']").on("blur", e =>{
$(e.target).popover("hide");
})
<script
src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css" integrity="sha512-5Hs3dF2AEPkpNAR7UiOHba+lRSJNeM2ECkwxUIxC1Q/FLycGTbNapWXB4tP889k5T5Ju8fs4b1P5z/iB4nMfSQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<label>
Some Text
<span>
<i
class='fas fa-question-circle descPopover'
tabindex="0"
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc', this)"
></i>
</span>
</label>
<label>
Some Other Text
<span>
<i
class='fas fa-question-circle descPopover'
tabindex="0"
aria-hidden='true'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-trigger="focus"
data-html="true"
data-content="<div id='descContainer'>Loading...</div>"
title="Click for more info"
onclick="showDescr('vpc', this)"
></i>
</span>
</label>
As you see, I am passing a second argument to the onclick handler, so that for each element, the handler has access to the element that triggered the call.
showDescr('vpc')
=> showDescr('vpc', this)
I have also switched to $().attr
to make this work, along with switching over to toggle
instead of show
so that the handler automatically hides/shows the element. Otherwise, you'll get a flickering issue, when the code tries to show an already open popover.
I've also included a working demo. Open and try the snippet.
Update: in order for the popover to toggle on 'blur' (while the user clicks on another part of the DOM), I've added a required tabindex
on the 2 elements and an onblur handler to hide the popovers.