I'm using Twitter Bootstrap's popover on the dynamic list. The list item has a button, when I click the button, it should show up popover. It works fine when I tested on non-dynamic.
this is my JavaScript for non-dynamic list
$("button[rel=popover]").popover({
placement : 'right',
container : 'body',
html : true,
//content:" <div style='color:red'>This is your div content</div>"
content: function() {
return $('#popover-content').html();
}
})
.click(function(e) {
e.preventDefault();
});
However, It doesn't work well on dynamic list. It can show up when I click the button "twice" and only show up one of list items I click fist time.
MY html:
<ul id="project-list" class="nav nav-list">
<li class='project-name'>
<a >project name 1
<button class="pop-function" rel="popover" ></button>
</a>
</li>
<li class='project-name'>
<a>project name 2
<button class="pop-function" rel="popover" ></button>
</a>
</li>
</ul>
<div id="popover-content" style="display:none">
<button class="pop-sync"></button>
<button class="pop-delete"></button>
</div>
My JavaScript for dynamic:
$(document).on("click", "#project-list li" , function(){
var username = $.cookie("username");
var projectName = $(this).text()
$("li.active").removeClass("active");
$(this).addClass("active");
console.log("username: " +username + " project name: "+projectName );
});
$(document).on("click", "button[rel=popover]", function(){
$(this).popover({
placement : 'right',
container : 'body',
html : true,
content: function() {
return $('#popover-content').html();
}
}).click(function(e){
e.preventDefault();
})
});
//for close other popover when one popover button click
$(document).on("click", "button[rel=popover]" , function(){
$("button[rel=popover]").not(this).popover('hide');
});
I have searched similar problems, but I still can't find the one to solve my problem. If anyone has some ideas, please let me know. Thanks your help.
Update
If your popover is going to have a selector that is consistent then you can make use of selector
property of popover constructor.
var popOverSettings = {
placement: 'bottom',
container: 'body',
html: true,
selector: '[rel="popover"]', //Sepcify the selector here
content: function () {
return $('#popover-content').html();
}
}
$('body').popover(popOverSettings);
Demo
Other ways:
Mutation Event
/Mutation Observer
to identify if a particular element has been inserted on to the ul
or an element.var popOverSettings = { //Save the setting for later use as well
placement: 'bottom',
container: 'body',
html: true,
//content:" <div style='color:red'>This is your div content</div>"
content: function () {
return $('#popover-content').html();
}
}
$('ul').on('DOMNodeInserted', function () { //listed for new items inserted onto ul
$(event.target).popover(popOverSettings);
});
$("button[rel=popover]").popover(popOverSettings);
$('.pop-Add').click(function () {
$('ul').append("<li class='project-name'> <a>project name 2 <button class='pop-function' rel='popover'></button> </a> </li>");
});
But it is not recommended to use DOMNodeInserted Mutation Event for performance issues as well as support. This has been deprecated as well. So your best bet would be to save the setting and bind after you update with new element.
Another recommended way is to use MutationObserver instead of MutationEvent according to MDN, but again support in some browsers are unknown and performance a concern.
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
// create an observer instance
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
$(mutation.addedNodes).popover(popOverSettings);
});
});
// configuration of the observer:
var config = {
attributes: true,
childList: true,
characterData: true
};
// pass in the target node, as well as the observer options
observer.observe($('ul')[0], config);
Probably way too late but this is another option:
$('body').popover({
selector: '[rel=popover]',
trigger: 'hover',
html: true,
content: function () {
return $(this).parents('.row').first().find('.metaContainer').html();
}
});
I did this and it works for me. "content" is placesContent object. not the html content!
var placesContent = $('#placescontent');
$('#places').popover({
trigger: "click",
placement: "bottom",
container: 'body',
html : true,
content : placesContent,
});
$('#places').on('shown.bs.popover', function(){
$('#addPlaceBtn').on('click', addPlace);
}
<div id="placescontent"><div id="addPlaceBtn">Add</div></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With