Dynamically add a class to Bootstrap's 'popover' container

JqueryCssTwitter Bootstrap

Jquery 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("&times;");
    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:

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>
    });
});

Demo: http://jsfiddle.net/PRQfJ/

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKateView Question on Stackoverflow
Solution 1 - JquerySeth JefferyView Answer on Stackoverflow
Solution 2 - JquerycbaigorriView Answer on Stackoverflow
Solution 3 - JqueryKateView Answer on Stackoverflow
Solution 4 - JqueryEtjieView Answer on Stackoverflow
Solution 5 - JqueryEl KopytoView Answer on Stackoverflow
Solution 6 - JquerykdelmonteView Answer on Stackoverflow
Solution 7 - JqueryyuviView Answer on Stackoverflow
Solution 8 - JqueryJefferson Henrique C. SoaresView Answer on Stackoverflow
Solution 9 - JquerybchhunView Answer on Stackoverflow
Solution 10 - JqueryMarius IlieView Answer on Stackoverflow
Solution 11 - JqueryMunawer AzizView Answer on Stackoverflow
Solution 12 - JqueryHockicView Answer on Stackoverflow
Solution 13 - JqueryNguyen LinhView Answer on Stackoverflow
Solution 14 - JquerySerge KarimView Answer on Stackoverflow
Solution 15 - JqueryArerracView Answer on Stackoverflow
Solution 16 - JqueryEugeneView Answer on Stackoverflow
Solution 17 - JqueryVinod ChauhanView Answer on Stackoverflow
Solution 18 - JquerychimerawdView Answer on Stackoverflow
Solution 19 - JqueryShankar CabusView Answer on Stackoverflow
Solution 20 - JqueryAtaView Answer on Stackoverflow
Solution 21 - JqueryPat MigliaccioView Answer on Stackoverflow
Solution 22 - JqueryMesropView Answer on Stackoverflow