Creating A jQuery Plugin From Scratch
November 20th, 2008
The first few jQuery plugins I created were basically my attempt at doing prototype in jQuery. They were not idiomatic jQuery. I did a bit of googling and found some good examples and decided to write a really basic jQuery plugin just to cement the format in my head. I figured I would post it here both to further cement it and as a way for you to learn if you want. If you only want to see the end result, you can find it on GitHub.
Cross Library Safety
The first thing I do is create a wrapper function which allows me to use $ and not cause conflicts with other JavaScript frameworks that may be included. It is simple and looks like this:
(function($) {
// safe to use $ here and not cause conflicts
})(jQuery);
Create and Name Your Plugin Function
Next, I created the function inside which my plugin will reside. Whatever you name this function will be how you and others use your plugin.
(function($) {
$.fn.toggler = function() {
// the plugin functionality goes in here
}
})(jQuery);
I have emboldened the function name in the code above to make it obvious. This means that to use the plugin I am creating, someone would have to do $('#some_selector').toggler().
Allow chainability
The next thing to keep in mind is that because jQuery takes any selector, you could be dealing with one or more objects. This means you need to be sure that your plugin loops through each element matched by the selector and applies the plugin functionality.
(function($) {
$.fn.toggler = function() {
return this.each(function() {
// apply plugin functionality to each element
});
}
})(jQuery);
The other thing you will notice about the addition above is that I use return. One of the cool things about jQuery is the chainability (ie: $('#some_div').hide().remove()). Returning the this.each iteration allows your plugin to be chained with other jQuery operations and plugins.
Start Building Plugin Functionality
The goal of the plugin I was creating was to allow saying that a particular link is a toggler. So what is a toggler you ask? A toggler is a link that toggles the visibility of another element on the page. The connection of the link to the element is by using the href. By setting the link’s href to anchor to the id of another element, we get two things for free. First, if JavaScript is not enabled, the link will still anchor to the element on the page. Second, we know which element the link is suppose to toggle display for. Take the following html for example:
<p><a href="#foo" class="toggler">Toggler</a></p>
<div id="foo">Togglee</div>
The default behavior of the toggler link is to anchor to the Togglee div wherever it is on the page. We will then use the jQuery plugin we are making to hide the togglee div on page load and then toggle its display each time the toggler link is clicked. First, let’s hide the togglee div and add the click observer to the toggler link.
(function($) {
$.fn.toggler = function() {
return this.each(function() {
this.togglee = $($(this).attr('href')).hide();
$(this).click(onClick);
});
}
})(jQuery);
The first bold line sets a togglee attribute on the toggler that is equal to the togglee jQuery element. Note the $(this).attr('href'). Using the html from above, this would return #foo. $('#foo') is equivalent to a jQuery object of the togglee div. We call hide() to hide the div by default. Because jQuery allows chaining, the hide() call returns the togglee jQuery object and we save a line of code. The long hand way of writing that line would be something like this:
this.togglee = $($(this).attr('href'));
this.togglee.hide();
Because jQuery allows chaining, lines like the ones above can be combined and in my opinion remain readable. Chaining too many things together can lower readability and the obviousness of intent though, so always practice safe chaining.
Observing Clicks
The $(this).click(onClick); line above tells the toggler (which is $(this)) to run the function onClick whenever it gets clicked. We haven’t yet created the onClick function so let’s do that now.
(function($) {
$.fn.toggler = function() {
return this.each(function() {
this.togglee = $($(this).attr('href')).hide();
$(this).click(onClick);
});
function onClick() {
this.togglee.toggle()
return false;
}
}
})(jQuery);
this is automatically set to the element that fired the onClick, by jQuery, which is our toggler link. Because we assigned the togglee attribute to the toggler link, we can simple call this.togglee.toggle() and it will toggle the display of the togglee div. The return false tells the togglee link to not actually fire the normal event, which would append #foo to the window location.
Allowing For Options
At this point, we could be done but why not allow some options for our plugin. In this case, we’ll add the option to make the togglee div animate with a slide instead of simply showing and hiding. Check out the bold lines in the cold sample below to see what is needed to add options.
(function($) {
$.fn.toggler = function(options) {
var opts = $.extend({}, $.fn.toggler.defaults, options);
return this.each(function() {
this.togglee = $($(this).attr('href')).hide();
$(this).click(onClick);
});
function onClick() {
this.togglee[opts.animate ? 'slideToggle' : 'toggle']();
return false;
}
}
$.fn.toggler.defaults = {animate: false}
})(jQuery);
The first bold line sets the opts variable and uses jQuery’s extend function to do so. Basically, $.extend is a merge tool. In plain english here is what happens: it merges $.fn.toggler.defaults on top of {} and then merges options on top of the first merge. It guarantees that our opts variable will be a hash ({}), will have some defaults ($.fn.toggler.defaults) and yet can be overridden on a per case basis with options passed in by you, the developer (options).
In the second bold line, we tell togglee to call slideToggle if opts.animate is true, otherwise just call toggle. This uses the ternary operator and some cool JavaScript functionality. If opts.animate is true, it returns 'slideToggle', otherwise it returns 'toggle'. This means if opts.animate is true, you would end up with this.togglee['slideToggle'](), which is the sweet functionality I referenced above that JavaScript natively provides. this.togglee['slideToggle'] is a reference to the slideToggle function and when you apply the parenthesis it will invoke the slideToggle function. I feel this way is more succinct, is still readable and again, it saves you a few lines and an if/else statement. Not a big deal, but worth it in this case.
The third and final emboldened line just sets the defaults that get used in the first line if no options are provided by you when you call toggler on some elements.
Example Uses With/Without Options
Now that we have options, you can call the toggler function any of the following ways and it will work.
// will do simple toggle on click
$('a.toggler').toggler();
// will use slideToggle instead of simple toggle on click
$('a.toggler.animate').toggler({animate:true});
That is pretty much it. You can now create a jQuery plugin that is jQuery-ish and has the ability to have options that can be adjusted on the fly, by you and the people who use your amazing plugin. The only other thing I would mention is most people seem to name their plugins jquery.{plugin name}.js. For example, I named this plugin jquery.toggler.js.
Overall, I am intrigued with jQuery. It doesn’t come with everything that Prototype does out of the box, but it is probably enough for most. Even if you do not switch to jQuery, I think it is important to give it a good run as it will help you think through JavaScript in a bit different light. As always, if I missed anything or I was unclear or wrong anywhere in the post, feel free to let me know and I will update.
If you enjoyed this post, get free updates by email or RSS.
Hey… It seems that you are quite jacked when it comes to JQuery plugins, so maybe you will be able to help me out.
How would a person go about changing a standard JS method into a JQuery Plugin (ie.):
//JavaScript ->
function change_innerHTML() {
document.getElementById(”element_to_change”).innerHTML = “XXXXXX”;
}
//HTML ->
YY
Your help will be much appreciated…
@Craig - there is a method built into jQuery that does html stuff.
Thanks for this tutorial.
How could this plugin (like your example) return an internal value.
For example a setting variable that could change internally.
If defaults.animate change because y create a new method that make it toggle from false to true, I like to know the value of animate.
something like this:
$(’a.toggler’).toggler();
.
.
.
var animateState = $(’a.toggler’).toggler(”state”);
and then animateState now have the value of $.fn.toggler.defauts.animate
I expect you understand what i tried to say.
Sorry my poor english
Willy
i noticed for your click events you used return false.
why not use : e.preventDefault();
good effort but your code could be done better. Its right now too hard for newbie to understand.
Your option is not standard as well.
Thank you. I’m so tired of reading articles that are trying to explain a subject to others and the try to write the code in 9 characters. I understand fully how important it is to reduce your code for various reasons. If the intent is to teach someone something new, then make the code easy for them to understand. By you taking the time to include an extra 4 or 5 lines of code to show what is happening internally made this article so clear. I have read a few articles on creating a plug-in. After reading their articles I never walked away with a clear picture on how to implement. I’m new to Jquery and js but I see how powerful these two can be in creating dynamic web sites and web applications.
once again,
thank you
@craig its true “Its right now too hard for newbie to understand.”