Extending the jQuery prototype to access Bootstrap components

Recently while transitioning some pages from jQuery-UI to Bootstrap, I found that one feature I missed (or rather, couldn’t find in the documentation) in Bootstrap is the ability to get references to the component object. For example, if we have a button and attach a popover to it, wouldn’t it be nice to grab the HTML of the popover so we can manipulate it later? Bootstrap exposes some functions via the .popover() call, but these mostly deal with toggling the visibility. While the Bootstrap documentation doesn’t explicitly point out how to do this, it’s quite simple to extend the jQuery prototype to get at the component object.

So given some HTML:

<input type='button' id='example' value="Example" />

and some Javascript to add a Bootstrap popover to that element:

$("#example").popover({
	title: 'Example popover',
	content: 'Let's get at this container.',
	placement: 'top'
});

we notice that Bootstrap itself doesn’t provide any way to grab the popover object. This is because it stores all the info that we need about the component in the trigger element’s jQuery data function:

// In Bootstrap 2.3 and under
$('#example').data('popover');

// In Bootstrap 3.0+
$('#example').data('bs.popover');// Note the new 'bs' namespace

From there we can access the options, enabled state, arrow and tip objects, a plethora of functions, and more. Care should be taken manipulating some of these elements directly as the result may not be quite as expected (especially when dealing with positioning).

Now, if we want to abstract the .data(‘popover’) call (ie. so that if we plan to transition from 2.x to 3.x we don’t have to change every call from ‘popover’ to ‘bs.popover’, or if we plan on making any changes to the returned object), we can extend the jQuery prototype (via $.fn) to add a function:

$.fn.getPopover = function() {
    return $(this).data('popover');// Or bs.popover in Bootstrap 3.0+
}

Then from there if we want to, say, add a class to the popover, we could easily call our getter and grab the element:

var popoverObject = $('#example').getPopover().$tip;
popoverObject.addClass('info');

It is also worth noting that elements that have arrows store them separately in the $arrow property; useful in case you plan on re-positioning the component.

If we wanted to further extend this logic for multiple components, we could create an array and iterate over it:

function createBootstrapGetters() {
    // Again, you need to prepend 'bs.' here for Bootstrap 3.0+
    var list = ['popover', 'tooltip', 'carousel'];

    $.each(list, function(i, name) {
        var capitalizedName = this.charAt(0).toUpperCase() + name.slice(1);

        $.fn['get' + capitalizedName] = function() {
            return $(this).data(name);
        }
    });
}

Finally, it’s worth mentioning that this technique may not work with all components (such as dropdowns), as their data attributes are a little different. However, those components are essentially equal to the trigger elements anyway, so manipulating their HTML should be a non-issue.

Igor Shults

About the Author

Object Partners profile.

One thought on “Extending the jQuery prototype to access Bootstrap components

  1. sam says:

    Thanks – saved the day with the name space issue.

Leave a Reply

Your email address will not be published.

Related Blog Posts
Building Better Data Visualization Experiences: Part 1 of 2
Through direct experience with data scientists, business analysts, lab technicians, as well as other UX professionals, I have found that we need a better understanding of the people who will be using our data visualization products in order to build them. Creating a product utilizing data with the goal of providing insight is fundamentally different from a typical user-centric web experience, although traditional UX process methods can help.
Kafka Schema Evolution With Java Spring Boot and Protobuf
In this blog I will be demonstrating Kafka schema evolution with Java, Spring Boot and Protobuf.  This app is for tutorial purposes, so there will be instances where a refactor could happen. I tried to […]
Redis Bitmaps: Storing state in small places
Redis is a popular open source in-memory data store that supports all kinds of abstract data structures. In this post and in an accompanying example Java project, I am going to explore two great use […]
Let’s build a WordPress & Kernel updated AMI with Packer
First, let’s start with What is an AMI? An Amazon Machine Image (AMI) is a master image for the creation of virtual servers in an AWS environment. The machine images are like templates that are configured with […]