Take a good start in jQuery plugins building

Today O my brothers, your humble narrator will teach you good practices for a good start in creating jQuery plugins.

Tue Oct 19 2010

Create a plugin is usefull for reuse your code for any dom elements and others websites with a simple : $('div, #id, .class').myPlugin();. In this tutorial, we will develop a plugin who add a twitter like word counter to textareas. We call the plugin wordCounter and the js file jquery.wordcounter.js.

Extend jQuery object

The first step is defining our plugin with the jQuery.fn function like this:

(function($) {
  $.fn.wordCounter = function(options) {
    ...
  };
})(jQuery);

As you notice, we encapsulate the code by an anonymous function with jQuery as a parameter named $ in order to use the jQuery alias without creating conflict with other libraries.

Parameters

We need 2 parameters : maxChar and warningColor. To have greater flexibility in managing our settings, we define them via a single JSON object and we do the same for default values.

(function($) {
  $.fn.wordCounter = function(options) {
    // define default parameters
    var defaults = {
      maxChar: 140,
      color: 'gray',
      warningColor: 'red'
    }
    options = $.extend(defaults, options);
  };
})(jQuery);

// example
$('textarea'). wordCounter( { maxChar: 100 } );

The extend jQuery function merges the two JSON objects. The variables defined when the plugin is called override those defaults. Thus our plug-in can run without any configuration.

The main code

We can now develop our main code keeping in mind two imperatives :

  1. use this.each() function for traversing all the jQuery DOM nodes,
  2. return the jQuery object so as to others methods can be chained.
(function($) {
  $.fn.wordCounter = function(options) {
    // define default parameters
    var defaults = {
      maxChar: 140,
      color: 'gray',
      warningColor: 'red'
    }
    options = $.extend(defaults, options);

    // traverse and return all nodes.
    return this.each(function() {

      // save the current node into an alias
      var $$ = $(this);
      var divCounter = $('<div>', {
        class: 'counter',
        text: options.maxChar,
        css: {
          color: options.color
        }
      }).insertBefore($$);
      updateCounter();

      // Key up event
      $$.bind('keyup', updateCounter);

      // Update counter function
      function updateCounter() {
        var nbLetters = $$.val().length;
        var counter = options.maxChar - $$.val().length;
        var color = (counter < 0) ? options.warningColor
                                  : options.color;
        divCounter.text(counter).css('color',color);
      }
    });
  };
})(jQuery);

Explanation

  • To begin, we create a <div> which display the number of available letters before the textarea.
  • updateCounter() is a function that calculates the difference between maxChar and the number of letters included in the text fields. Then it determines the color displayed and edit the <div> element.
  • Finally, we execute this function at the beginning and at each key up event.