jQuery - Easy Plugins
Written by Ian Elliot   
Monday, 11 February 2013
Article Index
jQuery - Easy Plugins
Chaining
Avoiding Collisions

Chaining

When you write a plugin you have to take great care what you decide to return. It can make your plugin very usable or very irritating. In most cases jQuery methods return a jQuery object, usually the one they were passed in the context, this, or a modified version of it.

The reason they return the jQuery object is because this allows the chaining of methods that makes jQuery so easy and powerful.

Of course you can't always fit in with this pattern. If your plugin needs to return some information such as the maximum height of an element say then it has to return a numeric result and chaining has to stop. However the situation is usually not as clear cut as this.

For example in our case the table plugin is currently returning a table object. Is this sensible? Well as the table object is currently appended to the first element in the jQuery object returning it doesn't make much sense. It seems more reasonable to return the jQuery object and allow chaining to continue. 

To do this the end of the function has to be written as:

 this.first().append(table);
 return this;
}

Now you can write:

$("div").table(3, 2).append("some text");

and the table object will be added to the first div and the text will then be added to the elements in the jQuery object in the usual way.

Does the final append add to all of the divs or just the first one in the selection?

The point is that the first() method reduces the selection to the first element so you might make the mistake of thinking that this is all the jQuery object you return contains. A moments thought should convince you that as we return this what append works on is the original jQuery object with all of the divs selected. Hence the text is added to all the div elements.

What if you want the table method to modify the selection? That is after using table only the first element is in the selection to be passed on to subsequent chained methods.

Once again the answer should be obvious - simply save the jQuery object you want to pass on and use it in the return. For example:

 var newjQuery=this.first().append(table);
 return newjQuery;
}

Now when you try:

 $("div").table(3, 2).append("some text");

only adds the text to the first div.

The rule is:

  • when your plugin is called this is a jQuery object of all the elements that have been selected. If you want to allow chaining you have to return a jQuery object - either the original or a modified one as appropriate.

In general, if your plugin's name doesn't sound as though it should change the selection, you are safer returning the unmodified selection.

If you want to be really clever you can opt to return something different if there are no selected elements. For example:

if(this.length===0){
 return table;
}else{
 this.first().append(table);
 return this;
}

Which returns the jQuery object that contains the table element if nothing is selected and the original jQuery object if there are selected elements. This lets you write:

var myTable=$().table(3, 2).append("some text"); $("#div2").append(myTable);

which appends the text to the table element and then lets you do what you want with the resulting DOM object.

If you do plan to make your plugin in vary what it returns make sure that it seems natural - in this case returning the table object seems to make sense as this is like appending it to nothing.

Even if it is obvious and natural, make sure you document it.

Options

There are lots of different parameters that your plugin supports then the best way of implementing this is to pass it an options object. If you haven't encountered the idea before an options object is simply an object with properties corresponding to the parameters you would have passed.

For example our table object has two parameter and these can be packaged up into an options object as:

{n:3,m: 2}

any additional parameters could be added as properties in the same way. When you call your plugin you now have to process the options object to extract the parameters, but this is easy:

function table(options) {
 var n=options.n;
 var m=options.m;

 

It is also a good idea to allow default options - after all what if the user didn't specify one of the properties. The simplest way to do this is to use the jQuery extend(obj1,obj2) method. This adds all of the properties of the second object to the first and returns the result.Notice that the extend method is an example of a method that belongs to the jQuery constructor - you call it using $.extend and not $().extend.

So to set defaults for n and m:

function table(options) {
 var settings=$.extend({n:2,m:2},options);
 var n=settings.n;
 var m=settings.m;

With this change you can call the plugin as:

$().table();

and automatically create a 2 by 2 table or as:

$().table({m:10})

and create a 2 by 10 table.

There are some subtle points in using extend. By default it creates a shallow copy. This means if one of the properties in the first object is itself an object this is simply overwritten by any property of the same name in the second object - it isn't merged with the property of the second object.

Using options and defaults is also the recommended way to vary the operation of your plugin. That is instead of creating two plugins that do similar jobs you should create a single plugin and use options to determine which exact job it does.  In particular you can use your plugin function as if it was a constructor for the plugins you want to use and simply pass it the name of the function you want to use.

For example if you want to add two related plugins - plug1 and plug2 you could set up an object within your main plugin:

function plugin(method,option) {
var plugins={
 plug1: function(options){  do plug1 };
 plug2: function(options){  do plug2 };
};

 

and to invoke the plugin you would use:

plugins[method];

So if you want to run plug2 you would write:

$().plugin("plug2",options);

In a real implementation you would need to also check that the user has specified a valid method and remember to return something at the end of plugin.

If you know jQuery UI you will recognize this method of invoking different sub-plugins and now you know how it works.

Of course, if the plugins you are creating are just for your own consumption then it is entirely up to you how many plugins you create as it is your own jQuery namespace that you are clogging up.



Last Updated ( Tuesday, 12 February 2013 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.