Making a jQuery Plugin Truly Customizable

Most if not all of the jQuery plugins out there have some level of customization. But very few of the plugin authors have mastered the very particular art involved.

Achieving the "optimum level" of customization is a bit of a balancing act… go too far either way and you've got an unusable plugin!

Bob and Sue

Let's say Bob has created a wicked new gallery plugin (called "superGallery") which takes a list of images and makes them navigable. Bob's thrown in some animation to make it more interesting. He's tried to make the plugin as customizable as possible, and has ended up with something like this:

[js]jQuery.fn.superGallery = function(options) { // Bob's default settings: var defaults = { textColor : '#000', backgroundColor : '#FFF', fontSize : '1em', delay : 'quite long', getTextFromTitle : true, getTextFromRel : false, getTextFromAlt : false, animateWidth : true, animateOpacity : true, animateHeight : true, animationDuration : 500, clickImgToGoToNext : true, clickImgToGoToLast : false, nextButtonText : 'next', previousButtonText : 'previous', nextButtonTextColor : 'red', previousButtonTextColor : 'red' }; var settings = $.extend({}, defaults, options); return this.each(function(){ // ---------------------------- // Plugin code would go here... // ---------------------------- }); };[/js]

The first thing that probably comes to your mind (ok, maybe not the first) is the prospect of how huge this plugin must be to accommodate such a level of customization. The plugin, if it weren't fictional, would probably be a lot larger than necessary. There are only so many kilobytes people will be willing to spend!

Now, our friend Bob thinks this is all fine; in fact, he's quite impressed with the plugin and its level of customization. He believes that all the options make for a more versatile solution, one which can be used in many different situations.

Sue, another friend of ours, has decided to use this new plugin. She has set up all of the options required and now has a working solution sitting in front of her. It's only five minutes later, after playing with the plugin, that she realizes the gallery would look much nicer if each image's width were animated at a slower speed. She hastily searches through Bob's documentation but finds no animateWidthDuration option!

Do you see the problem?

It's not really about how many options your plugin has; but what options it has!

Bob has gone a little over the top. The level of customization he's offering, while it may seem high, is actually quite low, especially considering all the possible things one might want to control when using this plugin. Bob has made the mistake of offering a lot of ridiculously specific options, rendering his plugin much more difficult to customize!

A better model

So it's pretty obvious: Bob needs a new customization model, one which does not relinquish control or abstract away the necessary details.

The reason Bob is so drawn to this high-level simplicity is that the jQuery framework very much lends itself to this mindset. Offering a previousButtonTextColor option is nice and simple, but let's face it, the vast majority of plugin users are going to want way more control!

Here are a few tips which should help you create a better set of customizable options for your plugins:

Don't create plugin-specific syntax

Developers who use your plugin shouldn't have to learn a new language or terminology just to get the job done.

Bob thought he was offering maximum customization with his delay option (look above). He made it so that with his plugin you can specify four different delays, "quite short," "very short," "quite long," or "very long":

[js]var delayDuration = 0; switch (settings.delay) { case 'very short' : delayDuration = 100; break; case 'quite short' : delayDuration = 200; break; case 'quite long' : delayDuration = 300; break; case 'very long' : delayDuration = 400; break; default : delayDuration = 200 }[/js]

Not only does this limit the level of control people have, but it takes up quite a bit of space. Twelve lines of code just to define the delaying time is a bit much, don't you think? A better way to construct this option would be to let plugin users specify the amount of time (in milliseconds) as a number, so that no processing of the option needs to take place.

The key here is not to diminish the level of control through your abstraction. Your abstraction, whatever it is, can be as simplistic as you want, but make sure that people who use your plugin will still have that much-sought-after low-level control! (By low-level I mean non-abstracted)

Give full control of elements

If your plugin creates elements to be used within the DOM, then it's a good idea to offer plugin users some way to access those elements. Sometimes this means giving certain elements IDs or classes. But note that your plugin shouldn't rely on these hooks internally:

A bad implementation:

[js]// Plugin code $('