How To Develop a jQuery Plugin

Contributing Editor

How To Develop a jQuery PluginjQuery is the most popular JavaScript library and many sites adopt it for dynamic effects and Ajax functionality. However, relatively few developers delve into the depths of plugin development.

In this tutorial, we will create simple plugin to explain the basics. Our code will reverse the text within one or more selected nodes — view a demonstration page.

Why Create a jQuery Plugin?

In a word: re-use. By extending jQuery, you create reusable components that can be used on any web page. Your code is encapsulated and there is less risk that you will use the same function names elsewhere.

How jQuery Works

At its core, jQuery is passed DOM elements or a string containing a CSS selector. It returns a jQuery object, which is an array-like collection of DOM nodes. One or more methods can then be chained to this set of nodes, e.g.


// color all <p> tags red
$("p").css("color", "red");

Note: although the jQuery library is named ‘jQuery’, ‘$’ is a shortcut variable that references it. Be aware that other libraries can grab ‘$’ for themselves.

How jQuery Plugins Work

jQuery allows methods to be added to its library. When called, these methods are passed the jQuery object within the JavaScript ‘this’ object. The DOM nodes can be manipulated as required and the method should return ‘this’ so other functions can be chained.

Our example plugin will be called using code such as:


// reverse the text in all <p> tags
$("p").reverseText();

We will also add two optional parameters, minlength and maxlength. When defined, the string length must fall between these limits for the reversal to occur.

The Plugin Declaration

Plugins are defined using the jQuery fn function, e.g.


jQuery.fn.reverseText = function(params) { ... };

Using ‘jQuery’ rather than ‘$’ ensures there are no conflicts with other JavaScript libraries. All our internal code should also refer to ‘jQuery’ rather than ‘$’. However, we can save a little typing and reduce the file size using an anonymous function:


(function($) {
	$.fn.reverseText = function(params) { ... };
})(jQuery);

This function runs immediately and is passed jQuery as a parameter named ‘$’. Since ‘$’ is a local variable, we can assume that it always refers to the jQuery library rather than another library that grabbed the global ‘$’ variable first.

Plugin Parameters

We require two parameters for our plugin: minlength and maxlength. It is easiest to define these as function arguments, e.g.


(function($) {
	$.fn.reverseText = function(minlength, maxlength) { ... };
})(jQuery);

// example
$("p").reverseText(0, 100);

But what if we decide to add further parameters later? Our plugin could have dozens of options — parameter handling would quickly become convoluted. As an alternative, we could pass a single JSON object, e.g.


(function($) {
	$.fn.reverseText = function(params) { ... }
})(jQuery);

// example
$("p").reverseText( { minlength: 0, maxlength: 100 } );

The first line in our reverseText function should define a set of default parameters then overwrite these with any user-defined values. The jQuery extend function can handle this for us:


// merge default and user parameters
params = $.extend( {minlength: 0, maxlength: 99999}, params);

Therefore, params.minlength is 0 and params.maxlength is 99999 unless the calling code overrides those values.

The Plugin Code

We can now write our main plugin code:


// traverse all nodes
this.each(function() {

	// express a single node as a jQuery object
	var $t = $(this);

	// find text
	var origText = $t.text(), newText = '';

	// text length within defined limits?
	if (origText.length >= params.minlength &&  origText.length <= params.maxlength) {

		// reverse text
		for (var i = origText.length-1; i >= 0; i--) newText += origText.substr(i, 1);
		$t.text(newText);

	}

});

Explanation:

  1. The this.each function traverses all the jQuery DOM nodes and calls an anonymous function.
  2. Within the function, ‘this’ contains a single node. A jQuery node collection is assigned to $t so we can run jQuery methods.
  3. The variable origText is assigned the text string within the DOM node. newText is set to an empty string.
  4. If the length of origText falls between params.minlength and params.maxlength, the loop creates a reversed text string in newText. The DOM node is then updated accordingly.

Don’t Break the Chain!

Finally, we should remember to return the jQuery object so other methods can be chained:


return this;

The Completed Code

Our plugin code is now complete:


(function($) {

	// jQuery plugin definition
	$.fn.reverseText = function(params) {

		// merge default and user parameters
		params = $.extend( {minlength: 0, maxlength: 99999}, params);

		// traverse all nodes
		this.each(function() {

			// express a single node as a jQuery object
			var $t = $(this);

			// find text
			var origText = $t.text(), newText = '';

			// text length within defined limits?
			if (origText.length >= params.minlength &&  origText.length <= params.maxlength) {

				// reverse text
				for (var i = origText.length-1; i >= 0; i--) newText += origText.substr(i, 1);
				$t.text(newText);

			}

		});

		// allow jQuery chaining
		return this;
	};

})(jQuery);

This file is saved as jquery.reversetext.js. We can then include it in any HTML page after the jQuery library has loaded, e.g.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>jQuery plugin: reverseText demonstration</title>
</head>
<body>

<h1>jQuery plugin: reverseText</h1>
<p>This jQuery plugin reverses all the text in the selected nodes.</p>

<ul>
<li>This text will be reversed</li>
<li>This text will not be reversed</li>
<li>reversed</li>
<li>not reversed</li>
</ul>

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.reversetext.js"></script>
<script type="text/javascript">
// reverse even-numbered LI tag text
$("ul li:even").reverseText();
</script>

</body>
</html>

The list in this page now has the text reversed on the first and third bullets (remember, the first item is numbered from 0):

reversed text

Resources:

You should now have a good understanding of jQuery plugin development. The SitePoint JavaScript forum is also a great resource for help and advice.

Coming soon: a new three-part tutorial describing how to build a useful page component as a jQuery plugin.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Tim

    The one thing that bugs me about jquery plugins is the endless list of js files you need to include in the page if you need a few loaded. It seems strange there isn’t (as far as I’m aware anyway) a method in the core for loading them all up and streaming them down as one file from the backend. This would reduce the number of http requests the client has to perform to get all the pieces.

  • http://blog.geekyjohn.com AussieJohn

    Pixelgraphics have a nice tool that allows you to quickly generate a plugin template. http://starter.pixelgraphics.us/

  • http://blog.geekyjohn.com AussieJohn

    @Tim: To only allow one HTTP request to get all your plugins loaded on a page, you wouldn’t be able to use only JavaScript – as JavaScript only has the capability to make a client-server request. The kind of solution you’re likely after would include some kind of server side interaction as well. For example, you could use a PHP loader script that grabs all your scripts and outputs them to the buffer and then serves it up as a JavaScript file. Something like:
    <script
    type="text/javascript"
    src="loader.php?scripts[]=someplugin.js&scripts[]=anotherplugin.js">
    </script>

    (Don’t forget that if you take this sort of implementation you’d need to do a bunch of security checking, to make sure you’re not loading sensitive files).
    You might even be able to use something like this in combination with the $.getScript() function in jQuery.

  • Froerst

    Thats a great quick tutorial. I’m starting to write my own,jQuery plugins but want to know how to best structure plugin code that start to become rather large.

    Also you can write:
    return this.each(function(){

    // code here

    })

    for chainability.

  • http://www.cemerson.co.uk Stormrider
  • Anonymous

    Nice tutorial. I’ve used it to create my first plugin this morning which I’ll be publishing over the weekend if I can figure out how to use git in eclipse =)

  • http://www.lunadesign.org awasson

    @Tim: As AussiJohn says, you’ll have to use the server to bundle your scripts. I’ve achieved that successfully with Drupal sites that I have used JQuery with. It works just as you would expect it to.

  • http://james.padolsey.com JimmyP

    Or, more concisely:


    $.fn.reversetext = function(){
    return this.each(function(){
    $(this).text( $(this).text().split('').reverse().join('') );
    });
    }

  • Jared

    Absolutely enticing! I am about to begin learning JQUERY and really just can’t wait! Looks awesome! Everyone who is against JQUERY is always for writing their own library – but unless you can do better, why re-invent the wheel? Just ad to it!

  • http://blog.geekyjohn.com AussieJohn

    @JimmyP:

    Don’t forget when building plugins that it’s important you don’t directly reference the $ variable, to minimise interfering with local variables (possibly from other libraries). You can use the jQuery variable, or wrap your code in an anonymous function.
    (function($) {
    $.fn.reversetext = function(){ return this.each(function(){ [...] }) }
    })(jQuery);

  • AbhiTechBlog

    this is THE BEST article available online on creating jQuery plugin. You have taken care of almost every detail. Thanks a ton! :)

  • Sander Aarts

    { minlength: 0, maxlength: 100 } is not a JSON object, but a regular JavaScript object. JSON objects must have strings as keys, like { "minlength": 0, "maxlength": 100 }.

    In the example a regular JavaScript object works just fine, as would a JSON object.

    I read this mix up quite often lately. Please call it what it is, the JSON specs aren’t that difficult ;)

    http://json.org/

    cheers

  • Jacob

    Thanks man you just opened a door.

  • http://www.bazingadesigns.com Greg

    Thank you Craig, your tutorial put me straight into writing my own stuff