Building JQuery Widgets Part 2

In this article, we’re going to look at some of the finer aspects of the plugin we last build a little bit ago.  Let’s start by looking again at the _init method.  As I mentioned previously, this method runs when the plugin is initialized, after the _create method runs (if there is one).  On init, we have this definition.

_init: function() {

this.options = $.extend({

title: “Interactive Help”,

buttonText: “OK”,

alertIfHidden: true,

beforeShowCallback: null,

afterShowCallback: null,

nextCallback: null,

startingCallback: null,

finishCallback: null

}, this.options);    this._elements = [];

this._currentIndex = 0;

this._total = 0;



Notice the use of the $.extend method; this method is very handy for establishing default values.  The method takes the values passed into the first parameter, and passes it to the second object, only if a value doesn’t already exist.  This is a great way to ensure a field exists, and helps you from having to write a lot of code that checks for a property’s existence.  What I mean by that is if you didn’t use the extend method, if your plugin tries to use this.options.startingCallback, when startingCallback was never supplied in the options, then an startingCallback is undefined an an exception is the result.  Our implementation of extend above ensures a title, buttonText, etc. field exists on the options object, so we don’t have to do that type check.

Notice that we have some options with a “callback” extension; these are the equivalent to an event in .NET or some other object-oriented language.  An event in an object-oriented language is defined explicitly, allowing the consumer of that event to attach to it and receive notification when the event occurs.  Widgets have the same functionality, in a different way.  We can attach to the event handler by supplying a JavaScript function, and then invoke that function at the appropriate time At various points in the plugin, we’ll invoke the callback by doing the following:

if (!!this.options.nextCallback)

this.options.nextCallback(this, { index: this._currentIndex, total: this._total });

We invoke the method, if it exists, and pass in any additional parameters.  Another important point to note is that you as a developer can interact with the consumer through these callbacks.  For instance, take a look at the code below.

var args = $.extend({
oldElement: el,
oldLeft: (!!pos && !!pos.left) ? pos.left : null,
oldTop: (!!pos && !! ? : null,
element: null,
selectorFunction: null,
left: null,
top: null
}, def);if (!!this.options.beforeShowCallback)
this.options.beforeShowCallback(this, args);

if (!!args.element)
el = args.element;

if (!el && typeof(args.selectorFunction) !== “undefined”)
el = args.selectorFunction({ element: this.element });
if (!!el) {
pos = this._getElementPosition(el);

In this example, we construct an event argument that has specific parameters.  These parameters are passed to the beforeShow event, through the beforeShowCallback (notice the use of extend to ensure certain parameters exist).  After it’s called, the widget interrogates the argument object for any changes the user may have made.  For instance, the user may have supplied an element, or even a function for selecting the element.  In this way, users can provide the widget input at the time the event has executed, something we also have the ability to do in object-oriented languages.

When creating widgets that others on your development team, or possibly the world if  you release your widget to the public, the difficulty comes with how to let them know how to use your plugin, what parameters are available for each callback, and other aspects requiring documentation.  Without good documentation, that supply the parameters being passed in at initialization time or supplied by a callback, the consumer of the widget will have difficulty using it.  While we don’t always like documentation, providing it is key to your widget’s success.  Sure, the above average developer will read the source, but the rest of your audience will be left in the dark without good direction.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s