Declarative Initialization of jQuery Plugins

jQuery plugins provide great functionality and are pretty easy to use — just add to the page a line like this $('.some-class').somePlugin() and you are good to go. While this works very well for small websites, it turns into real mess when you have a large complex website with dozens of plugins used across hundreds of views (as in MVC pattern).

Basically you either have to sacrifice page loading speed (inline scripts pause document parsing) and html code beauty by inserting plugin initialization inline after the necessary DOM element or loose logical connection between a DOM element and the plugin by moving all initialization code to a separate js file.

Method I describe relies on usage of onclick property of DOM elements. Since content within onclick is parsed by a browser as JavaScript code we can use it to store configuration for our plugins. This approach is used by several JS library including i-bem, a JS library for BEM that I recommend checking out.

So how does this work? First of all we need some plain old jQuery plugin. I will use lightweight-datepicker for this example since it's really nice and has configuration options which is what we need. Let's say we have a field like this that needs a date picker:

<input type="text" id="date1">

Now we need a way to specify that this fields needs some query plugins applied to it, so we add a class:

<input type="text" id="date1" class="jquery-declarative-init">

Next thing we need is a way to specify which plugins we need so we add configuration as an onclick attribute:

<input type="text" id="date1" class="jquery-declarative-init" onclick="return {
    lwDatepicker: { autoFillToday: true }
}">

In options we use a hash where key is plugin name and value is a hash of options for the plugin. The remaining thing is rather trivial — we just search all elements with jquery-declarative-init class on document ready event and instantiate the plugins:

$(function() {
  $('.jquery-declarative-init').each(function() {
    // If there's no onclick configuration then we can't initialize anything
    if(typeof this.onclick !== 'function') return;

    // Getting a config and removing onclick handler
    var plugins = this.onclick();
    this.onclick = null;

    // Now we just iterate over the plugins and initialize them
    for (key in plugins)
      $(this)[key](plugins[key]);
  });
});

That's essentially it. You write that once and you can keep all the initialization code right next to the elements it's used on.

I've created a jQuery plugin with a little more bells and whistles.

Social comments Cackle