Dynamically add a class to Bootstrap's 'popover' container
JqueryCssTwitter BootstrapJquery Problem Overview
I've thoroughly searched through both StackOverflow and Google, but come up empty. So apologies in advance if this has been asked & resolved already.
NB: I'm a newbie at jQuery, so I'm not sure how to write this up myself. I'm sure this is an easy snippet of code, but can't wrap my head around it.
What I'm looking to do is use a data-
element (eg: data-class
or similar) to attach a new class (Or ID, I'm not picky anymore!) to the top-level popover <div>
. The code I currently have is as follows:
jQuery:
$('a[rel=popover]')
.popover({
placement : 'bottom',
trigger : 'hover'
})
.click(function(e) {
e.preventDefault()
});
HTML:
<a href="" rel="popover" data-class="dynamic-class" title="Title goes here" data-content="Content goes here">
And ideally the kind of HTML I would have spit out, is something like this:
<div class="popover ... dynamic-class">
<!-- remainder of the popover code as per usual -->
</div>
Is this something I can do? The documentation on the bootstrap site for popovers is a bit sparse, so it's taken me a while just to get to this point, unfortunately :(
Thanks in advance for any & all responses!
Jquery Solutions
Solution 1 - Jquery
You can do this without hacking Bootstrap and without changing the template either, by grabbing the popover object from the caller's data
and accessing its $tip
property.
$('a[rel=popover]')
.popover({ placement: 'bottom', trigger: 'hover' })
.data('bs.popover')
.tip()
.addClass('my-super-popover');
Solution 2 - Jquery
There is another way to do this in version 2.3 that is quite simple actually. You override the default template to include the class to the container.
var pop = $('a', this.el).popover({
trigger: 'click'
, template: '<div class="popover awesome-popover-class"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
});
Solution 3 - Jquery
Based on what @bchhun wrote and a lot of head scratching, I felt I should answer my own question, as I got it working. I also noticed this had been favourited and liked, so I hope I'm helping someone else who is a newbie at jQuery like myself.
In the current Bootstrap build [v2.1.0], the scripts are all consolidated. So if you have included all of the scripts in your build (and not edited any new lines/taken some out), then head to line 1108 of the un-minified .js
file. You'll find the following bit of code:
$tip
.css(tp)
.addClass(placement)
.addClass('in')
You're going to be adding a new line to this, which is:
.addClass(this.$element.attr("data-class"))
So now whenever you add data-class
to the popover call, it will add the attribute to the <div class="popover">
div.
Now that I see it, it's so obvious :)
Solution 4 - Jquery
Its an old post but I'm adding it just as reference. Modifying [Shankar Cabus][1] answer, instead of adding the dynamic-class to parent, it will be added in the created .popover div.
$(function(){
$('a[rel=popover]')
.popover({
placement : 'bottom',
trigger : 'hover'
})
.on("hover", function(){
$('.popover').addClass($(this).data("class")); //Add class .dynamic-class to <div>
});
});
Hope this helps :) [1]: https://stackoverflow.com/users/980377/shankar-cabus
Solution 5 - Jquery
How about adding that class ONLY to appropriate popover, without targeting others?
$('#someElement').popover({placement: function(context, src) {
$(context).addClass('my-custom-class');
return 'top'; // - 'top' placement in my case
});
or some variation, like taking custom class name from data of 'someElement', like so:
$('#someElement').popover({placement: function(context, src) {
$(context).addClass($(src).data('customClassName'));
return 'top';
});
Solution 6 - Jquery
Just set the hidden "template" option when initializing the tooltip. I don't know why the bootstrap team would keep this a secret...
$(elem).popover({
template: '<div class="popover YOURCLASS"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
}).popover('show');
Hope this helps...
Solution 7 - Jquery
This has been asked a few years ago, and there are plenty of answers. But... I recently had to tackle the same problem myself, and I - (a) wanted to avoid manipulating source code and (b) needed a generic solution to be reused constantly (so using the template: '...'
solution for each initialization was out).
My solution was simple enough, and is sort of the same as the marked answer - I figured popover is an extension of the tooltip.js
library. I mean - check it out, the source code is barely more than a hundred lines. So I created a file called popover-extend.js
, and copy-pasted the entire popover source code in.
From there it was easy - simple manipulate these lines:
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
// add this:
cls: ''
});
then:
Popover.prototype.setContent = function () {
// add this:
if (this.options.cls) {
$tip.addClass(this.options.cls);
}
Now you can do:
<a href="#" rel="popover"
data-cls="dynamic-class"
title="Title goes here" data-content="Content goes here">
It's a really good approach if you're like me and want to add more functionality. for example, here's how I added a generic close button to the title (though it requires the popover to have a specified id):
// added this to the the DEFAULTS
close: ''
// added this to the setContent function
if (this.options.close) {
var id = this.$element.attr('id'),
btn = $("<button></button>", {
"class": "close",
"id": "close",
"onclick": "$('#"+id+"').popover('hide');"
}),
title = $tip.find('.popover-title');
btn.html("×");
btn.appendTo(title);
}
The cool thing about it, is that everything you set in the DEFAULTS can be configured via html, i.e. if you add a variable named foo
, you will be automatically able to manipulate it through data-foo=
.
Hope this helps anyone looking for an alternative to manipulating source code
Solution 8 - Jquery
I had the same problem, I liked the answer of @Kate, but changes in the source file can generate so much problems in the future, you probably will forget these little changes when you update your bootstrap's version. So I found another way of doing that:
$(element).popover({...}).data("popover").tip().addClass("your_class")
As @CorayThan fix it with data("popover")
The method tip() of popover returns the popover element, and creates when it is not created, therefore you will always get the correct popover element, even if you are at the initialization of popover (This is my case =D ).
Solution 9 - Jquery
It's getting late over here and I'm getting tired but here's a quick one-liner that won't work in the future if you decide to update bootstrap's js files.
Take a look at the bootstrap-tooltip.js file in this gist on line 150.
And here's the modified tooltip in action:
Checkout the inspector's window down there and you'll notice that the dynamic-class has been added to the tooltip.
I'll post a more long-termable & appropriate answer tomorrow.
Solution 10 - Jquery
This works for me. It is inspired by the bootstrap's documentation from here, the Events section.
$("a[rel=popover]").popover().on("show.bs.popover", function(){
$(".popover").addClass("your-custom-class");
});
Solution 11 - Jquery
Also you can make use of 'template' options
$element.popover({
html: true,
trigger: 'click',
template: '<div class="popover '+MY_CLASS+'" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
content: function() {
return 'hello';
}
});
Update MY_CLASS from you data-class attribute.
Solution 12 - Jquery
You could use the container
option to get around this.
$('[data-toggle="popover"]').popover({
container: '#foo'
});
or set it through a tag attribute
<a href="#" data-toggle="popover" data-container="#foo" data-content="Content">Foo</a>
And add this somewhere before closing the body tag
<div id="foo"></div>
Then you could do something like #foo > .popover
. I know this is not a one-size-fits-all solution but it's one way to do it.
Solution 13 - Jquery
This extend your class from out side bootstrap core class
, just add the attribute data-class
and an option dataClass:
true to your tooltip
function
!function($){
$.extend($.fn.tooltip.Constructor.DEFAULTS,{
dataClass: false
});
var Tooltip = $.fn.tooltip.Constructor;
_show = Tooltip.prototype.show;
Tooltip.prototype.show = function (){
_show.apply(this,Array.prototype.slice.apply(arguments));
if (this.options.dataClass!=="undefined" && this.options.dataClass){
var that = this;
var $tip = this.tip();
if (this.$element.attr("data-class") !== undefined)
$tip.addClass(this.$element.attr("data-class"));
}
};
}(jQuery);
Solution 14 - Jquery
for bootstrap v3.3.2 you find these lines on bootstrap.js
$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
.addClass(placement)
.data('bs.' + this.type, this)
Then you add this line
.addClass(this.$element.attr("data-class"))
Now to add a class on your popover element, you will be just putting an attribute
data-class="classexemple"
then everything works perfect
Find us on http://www.mixpres.com">www.mixpres.com</a>
Solution 15 - Jquery
In Bootstrap 4 you can use the data-template
attribute:
<button data-toggle="popover" data-template='<div class="popover MYSUPERCLASS" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' data-offset="-10 0" data-html="true" data-trigger="focus" data-placement="bottom" data-content='My Popover'>Button</button>
Solution 16 - Jquery
$('a[rel=popover]')
.popover({ placement: 'bottom', trigger: 'hover' })
.data('bs.popover')
.addAttachmentClass('my-own-popover')
You'll get bs-popover-my-own-popover
class inside .popover
element.
Solution 17 - Jquery
The best solution for this problem is to extend the popover and built your own version of Popover. Below is the code and it's based on bootstrap version 3.3.7
(function($){
var PopoverEx = function(element, options){
this.init('popover', element, options);
}
PopoverEx.prototype = $.extend({}, $.fn.popover.Constructor.prototype, {
constructor: PopoverEx,
tip: function(){
if(!this.$tip){
this.$tip = $(this.options.template);
if(this.options.modifier) this.$tip.addClass(this.options.modifier);
}
return this.$tip;
}
});
$.fn.popoverex = function(option){
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.popover', (data = new PopoverEx(this, options)))
if (typeof option == 'string') data[option]()
})
}
})(window.jQuery);
Usage
HTML Code
<a href="#" class="btn btn-large btn-danger"
rel="popover"
data-modifier="popover-info"
title="A Title"
data-content="And here's some amazing content.right?">Hover for popover</a>
JS script
jQuery(document).ready(function($) {
$('[rel="popover"]').popoverex();
});
You will find full version and description from this git page https://gist.github.com/vinoddC/475669d94e97f4d7b6bcfde4cef80420
It's a updated version of Brian Woodward's work.
Solution 18 - Jquery
I know this thread is old, but for those who stumble across this article as I did, here is another method that will allow more customisation. I haven't tested it with Bootstrap 4 but it with Bootstrap 3.
Instead of hard-coding a class in the function, you can 'submit' a css class to your popover via your html element using a custom data attribute. For this example I've called that attribute "data-class".
As this method exploits the function available to the popovers 'placement' options, I've configured it to preserve the original placement configured in the popover.
jQuery( '[data-toggle="popover"]' ).popover({
container: 'body',
placement: function ( popover, trigger ){
// Get the submitted placement for the popover
var placement = jQuery( trigger ).attr( 'data-placement' );
// Get the class(es) to apply to the popover
var dataClass = jQuery( trigger ).attr( 'data-class' );
// Apply the submitted class(es) to the popover element
jQuery( popover).addClass( dataClass );
// Return the original placement for the popover
return placement;
},
trigger: 'hover'
});
I hope this helps. If anyone has a better or cleaner way of doing this I'd be happy to learn :)
Solution 19 - Jquery
Sorry, but did not quite understand your question ... But what you want is to add a parent div? Take it easy ... See if this is what you want:
$(function(){
$('a[rel=popover]')
.popover({
placement : 'bottom',
trigger : 'hover'
})
.on("click", function(){
$(this).closest("div").addClass($(this).data("class")); //Add class .dynamic-class to <div>
});
});
Solution 20 - Jquery
best option that works on every vesion of BS, is to make it inside a specefic class and after showing that, find that class, and add your classname to popover parrent of it
// create a template that add the message inside
var $tmp = $("<div class='popoperrormessage'>" + error + "</div>");
$(this).popover("destroy").popover({
trigger: "manual",
animation: false,
html: true,
placement:"right",
content: $tmp,
container: "body"
}).popover("show");
// now we have to find the parent of the popoperrormessagemessage
$(".popoperrormessage").parents(".popover").addClass("hello");
Now your popover will have hello class
Solution 21 - Jquery
Here is my workaround, probably not the most efficient but I found it the easiest to implement.
$('[data-content]').each(function(){
var options = {
html: true //optional
};
if ($(this)[0].hasAttribute('data-class')) {
options['template'] = '<div class="popover" role="tooltip ' + $(this).attr('data-class') + '"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>';
}
$(this).popover(options);
});
Just add data-class="custom-class"
to the element like the other examples.
Solution 22 - Jquery
I'm not sure why you want to do this, but in my example, I just wanted to set custom style... So in CSS just written right selector for current popover. a.rating-popover - this is my link for opening popover. -> the popover element will be generated to the next of that element. so we can select it with
a.rating-popover + div.popover{
background: blue;
}
and voila, blue background. for only popovers opened with a.rating-popover element.