jquery plugin template

jQuery Plugin Tutorial

jquery.plugin-template.js

Use jQuery's data() method to store data in the DOM

jQuery has a .data() method for storing data in the DOM should you need to for one reason or other. This is preferable to storing data in some other attribute such as "rel" or "alt" which is often seen in tutorials and examples on blogs.


For example if you had a elements with the id "foo" and "bar" you could set data with a name of "fruit" to "orange" for #foo and "banana" for #bar like so:

$('#foo').data('fruit', 'apple'); $('#bar').data('fruit', 'banana'); 

To fetch the value at a later time call the .data() method just passing in the name like so, where the value is displayed in an alert dialog:

alert( $('#foo').data('fruit') ); 

If you don't want to assign the data to a particular element you could always assign it to the body instead:

$('body').data('fruit', 'orange'); alert( $('body').data('fruit') );

jQuery Plugin Tutorial

The Basics

A plugin is written as a method or function.

Creating a jQuery Function

Syntax

The function has to return this.each(..) to maintain chainability – so that the function can be used with a single or several jQuery objects.

jQuery.fn.myFunction = function(){
    return this.each(function(){
        // element-specific code here
    });
};

Example

jQuery.fn.makeTextRed = function(){
    return this.each(function(){
        $(this).css('color''red');
    });
};
 
// Example usage
$('#my-div').makeTextRed()// make text in "my-div" red
$('p').makeTextRed()// make all paragraphs red


Creating a jQuery Method

Syntax

jQuery.myMethod = function(){
    // code here
};

Example

jQuery.sayHelloWorld = function(){
    alert('Hello World');
};
 
// Example usage
$.sayHelloWorld()// alerts "Hello World"


Options

Make your plugin as flexible and user friendly as possible using options. The $.extend() method takes two or more objects as arguments and merges the contens of them into the first object.

Example

A function that set text color (red by default).

jQuery.fn.makeTextColored = function(settings){
    var config = {
        'color''red'
    };
    if (settings){$.extend(config, settings);}
 
    return this.each(function(){
        $(this).css('color', config.color);
    });
};

We can now choose use this function passing the settings parameter or not.

$('#my-div').makeTextColored()// make text red (default)
$('#my-div').makeTextColored('blue')// make text blue


Compatibility

As the $ variable might be used by other plugins, use a alias technique to make your plugin forward-compatible.

(function($){
$.fn.myFunction = function() {
    return this.each(function() {
        // element-specific code here
    });
 };
})(jQuery);

We pass jQuery to the function and can now use whatever alias for jQuery we like. So instead of $ you could also use any other valid JavaScript variable name.

The jQuery Plugin Checklist

This is a list of important points to remember when developing a jQuery plugin (from jQuery.com).

  • Name your file jquery.[insert name of plugin].js, eg. jquery.debug.js
  • All new methods are attached to the jQuery.fn object, all functions to the jQuery object.
  • inside methods, this is a reference to the current jQuery object.
  • Any methods or functions you attach must have a semicolon (;) at the end – otherwise the code will break when compressed.
  • Your method must return the jQuery object, unless explicity noted otherwise.
  • Use this.each to iterate over the current set of matched elements.
  • Always attach the plugin to jQuery instead of $, so users can use a custom alias via noConflict().

jQuery Plugin Templates

These are two good code templates to start from when developing a jQuery plugin.

Function Template

(function($){
    $.fn.myPlugin = function(settings){
        var config = {
            'foo''bar'
        };
        if (settings){$.extend(config, settings);}
 
        return this.each(function(){
            // element-specific code here
        });
    };
})(jQuery);

Method Template

(function($){
    $.myPlugin = function(settings){
        var config = {
            'foo''bar'
        };
        if (settings){$.extend(config, settings);}
 
        // code here
 
        return this;
    };
})(jQuery);


Why a plugin?


First of all, you might ask yourself why you'd want to develop a plugin. The first and best reason is the ability to maintain chainability. When people ask me the best feature of jQuery, I'd probably mention the chainability. It allows you do do things like:


$('.className').addClass('enabled').append('<a href="#">Click here</a>').click( func );


This would take every element with a class name of 'className', add a new class name to it, append some HTML, and set a click event handler. When you develop a plugin, you have the ability to intject your own functionality while still maintaining the chain.


Another reason to develop a jQuery plugin is simply to be consistent with the jQuery ethos. The jQuery ethos, in my opinion, is that the HTML element is king (or queen — lest I be mysoginistic about my HTML elements). It's all about getting elements and then performing actions on those elements.


Now, let's take a look at how to create a plugin, of which there are two possible approaches.

Approach 1: The Function

The documentation has a good example of the functional approach.

jQuery.log = function(message) {
  if(window.console) {
     console.debug(message);
  } else {
     alert(message);
  }
};

In this example, a log function has been attached to the jQuery object. You can then call this in your code using jQuery.log('my message') or $.log('my message'). There's no chainability or HTML elements involved (unless you add that into your code).


Approach 2: The Method

The method approach, gives you access to the current set of HTML elements and allows you to continue the chain. (Cue up the Pretenders, if you must.) Once again, the code is really simple... add the new function to jQuery.fn and make sure to return this.

jQuery.fn.newMethod = function(){
    return this;
}
;
The this keyword refers to the current jQuery object. You'll have access to jQuery's methods and functions. If you need to perform an action on each element then you can do something like this:

jQuery.fn.newMethod = function(){
    return this.each(function(){
        alert(this);
    });
};

The this keyword within the inner function refers to the current HTML element, which won't have access to the jQuery methods (although, it's as easy as wrapping it in the jQuery object to get those methods back).

Don't use $

When developing a plugin, you'll want to avoid using the familiar dollar function, $, to avoid any conflicts. jQuery has a no-conflict mode for turning the alias on and off. If you want, you can alias the jQuery function within your plugin. It'll be self-contained and avoid any outside conflicts.

If you do want to use $ in your plugin, the best was is as such:

(function ($) {
  $.fn.newMethod = function () {
    return this.each(function () {
      alert(this);
    });
  };
})(jQuery);

For times when you need something in between a basic method and a full-fledged plugin, it can be handy to extend jQuery directly.

For example:


jQuery.fn.extend({
sample : function() {
// do something and keep chaining
return this;
},
});



Example: jQuery Slideshow Plugin

I have chosen to use very simple examples so far in order for you to get started. The following example is a bit more complex and might help to get your inspiration going.

It uses the function setInterval() in combination with the jQuery effects fadeOut() andfadeIn() to cycle any number of images within a HTML-element.

The Setup

HTML

<div id="slideshow">
    <img src="img/sample-image-1.png" alt="" />
    <img src="img/sample-image-2.png" alt="" />
    <img src="img/sample-image-3.png" alt="" />
    <img src="img/sample-image-4.png" alt="" />
</div>

CSS

#slideshow img {
    display: none;
    position: absolute;
}

JavaScript

(function($){
    $.simpleSlideShow = function(selector, settings){
        // settings
        var config = {
            'delay'2000,
            'fadeSpeed'500
        };
        if ( settings ){$.extend(config, settings);}
 
        // variables
        var obj = $(selector);
        var img = obj.children('img');
        var count = img.length;
        var i = 0;
 
        // show first image
        img.eq(0).show();
 
        // run slideshow
        setInterval(function(){
            img.eq(i).fadeOut(config.fadeSpeed);
            i = ( i+1 == count ) ? 0 : i+1;
            img.eq(i).fadeIn(config.fadeSpeed);
        }, config.delay);
 
        return this;
    };
})(jQuery);

Usage

To enable slideshow on the #slideshow div, we simply call it using the following JavaScript code:

<script type="text/javascript">
$.simpleSlideShow('#slideshow');
</script>

Because we allow settings to change the behaviour of the slideshow, we could make it wait 5 seconds between images and set the “fade” duration to 200 ms using:

<script type="text/javascript">
$.simpleSlideShow('#slideshow', {'delay':5000, 'fadeSpeed': 200});
</script>

Example 2:

jQuery.fn.secondPlugin = function (number1, number2, options) {
myoptions = jQuery.extend ({
operation: "sum",
label: "The result is"
}, options);
 
$(this).html (myoptions.label + " (" + myoptions.operation + ")" + myoptions.number1+myoptions.number2);
}

In the above code, check out the way we provide default settings in case the two strings are not passed to the plugin function. This way we can call either

$('#test').secondPlugin (1, 2);

to get

<span id="test The result is (sum) 3</span>

or

$('#test').secondPlugin (1, 2, { operation: "sums two numbers together", label: "We got" });

if you prefer

<span id="test We got (sums two numbers together) 3</span>

Example 3:

The jQuery Object: Custom Functions and Selectors

Until now, we've messed with the jQuery.fn object, which is responsible for elements interaction, and we never mentioned the jQuery object itself, which handles internal processing. By extending it, we are thus allowed to create our own functions and even selectors for others to use! Here's how new methods can be added:

jQuery.fn.extend ({
myFirstFunction : function () { alert ("first function") },
thisIsTheSecond : function (message) { alert ("2nd: "+ message) }
});

and then called without any problems

$.myFirstFunction ();
$.thisIsTheSecond ("hello");

In a very similar fashion you can create your own selectors, provided they don't exist yet.

jQuery.expr[":"].startsWith = function (element, index, tokens) { 
if (!tokens[3]) return false;
return eval ("/^[/s]*" + tokens[3] + "/i").test ($(element).text());
};

As you can see, the function takes three arguments, being: 1) the matched element, 2) the index of the element and 3) an object that contains parse tokens; the first element of the array is the full filter string (including parameters), the second one is the ":", the third one is the filter name and, finally, the fourth is the parameter.

You should always check whether the parameter has been passed or not, since the filter could stop working in the latter case.


Example 4:


01$.fn.makeDiv = function(options) {//set up the function and give it a name
02    settings = $.extend({//set the default values for the options
03        color : 'white',
04        background : 'blue',
05        width : 400,
06        height : 100,
07    }, options);
08    $(this).css({//set the css properties of the selected element
09        color : settings.color,
10        background: settings.background,
11        width : settings.width,
12        height : settings.height
13    });
14};


<script>
2$(document).ready(function(){
3    $('div').makeDiv();
4});
5</script>

01<script>
02$(document).ready(function(){
03    $('div').click(function(){
04        $('div').makeDiv({
05            background: 'green',
06            color: 'black',
07            height: 200,
08            width: 50
09        });
10    });
11});
12</script>

Example5:

(function($){

$.fn.center = function(){

var element = this;

$(element).load(function(){

changeCss();

$(window).bind("resize", function(){
    changeCss();
});

function changeCss(){

    var imageHeight = $(element).height();
    var imageWidth = $(element).width();
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    $(element).css({
        "position" : "absolute",
        "left" : windowWidth / 2 - imageWidth / 2,
        "top" : windowHeight /2 - imageHeight / 2
    });
};
});

};

})(jQuery);

test:

 <script type="text/javascript">
    $(function(){
        $('img').center();
    });
    </script>