jQuery Plugin Boilerplate

Get the latest updates on this jQuery plugin via RSS
 
Please refer to the new version of the jQuery Plugin Boilerplate
 

A boilerplate for jump-starting jQuery plugins development.

Contains lots of comments to help you get going easily. It implements public and private methods, as well as public and private properties making it the ideal candidate for when building both simple and complex jQuery plugins.

It does not adhere to the suggestions made by the jQuery documentation regarding Plugins/Authoring.

The jQuery Plugin Boilerplate took some inspiration from Doug Neiner‘s Starter.

With comments:

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

// remember to change every instance of "pluginName" to the name of your plugin!
(function($) {

    // here we go!
    $.pluginName = function(element, options) {

        // plugin's default options
        // this is private property and is  accessible only from inside the plugin
        var defaults = {

            foo: 'bar',

            // if your plugin is event-driven, you may provide callback capabilities
            // for its events. execute these functions before or after events of your 
            // plugin, so that users may customize those particular events without 
            // changing the plugin's code
            onFoo: function() {}

        }

        // to avoid confusions, use "plugin" to reference the 
        // current instance of the object
        var plugin = this;

        // this will hold the merged default, and user-provided options
        // plugin's properties will be available through this object like:
        // plugin.settings.propertyName from inside the plugin or
        // element.data('pluginName').settings.propertyName from outside the plugin, 
        // where "element" is the element the plugin is attached to;
        plugin.settings = {}

        var $element = $(element), // reference to the jQuery version of DOM element
             element = element;    // reference to the actual DOM element

        // the "constructor" method that gets called when the object is created
        plugin.init = function() {

            // the plugin's final properties are the merged default and 
            // user-provided options (if any)
            plugin.settings = $.extend({}, defaults, options);

            // code goes here

        }

        // public methods
        // these methods can be called like:
        // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
        // element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside 
        // the plugin, where "element" is the element the plugin is attached to;

        // a public method. for demonstration purposes only - remove it!
        plugin.foo_public_method = function() {

            // code goes here

        }

        // private methods
        // these methods can be called only from inside the plugin like:
        // methodName(arg1, arg2, ... argn)

        // a private method. for demonstration purposes only - remove it!
        var foo_private_method = function() {

            // code goes here

        }

        // fire up the plugin!
        // call the "constructor" method
        plugin.init();

    }

    // add the plugin to the jQuery.fn object
    $.fn.pluginName = function(options) {

        // iterate through the DOM elements we are attaching the plugin to
        return this.each(function() {

            // if plugin has not already been attached to the element
            if (undefined == $(this).data('pluginName')) {

                // create a new instance of the plugin
                // pass the DOM element and the user-provided options as arguments
                var plugin = new $.pluginName(this, options);

                // in the jQuery version of the element
                // store a reference to the plugin object
                // you can later access the plugin and its methods and properties like
                // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
                // element.data('pluginName').settings.propertyName
                $(this).data('pluginName', plugin);

            }

        });

    }

})(jQuery);

Without comments:

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

(function($) {

    $.pluginName = function(element, options) {

        var defaults = {
            foo: 'bar',
            onFoo: function() {}
        }

        var plugin = this;

        plugin.settings = {}

        var $element = $(element),
             element = element;

        plugin.init = function() {
            plugin.settings = $.extend({}, defaults, options);
            // code goes here
        }

        plugin.foo_public_method = function() {
            // code goes here
        }

        var foo_private_method = function() {
            // code goes here
        }

        plugin.init();

    }

    $.fn.pluginName = function(options) {

        return this.each(function() {
            if (undefined == $(this).data('pluginName')) {
                var plugin = new $.pluginName(this, options);
                $(this).data('pluginName', plugin);
            }
        });

    }

})(jQuery);

Usage

$(document).ready(function() {

    // attach the plugin to an element
    $('#element').pluginName({'foo': 'bar'});

    // call a public method
    $('#element').data('pluginName').foo_public_method();

    // get the value of a property
    $('#element').data('pluginName').settings.foo;

});

Top

Requirements

jQuery 1.5.2+

It’s the only version I’ve tested the boilerplate with; it may be applicable to earlier versions, too. If you can test, please let me know. Thanks!

Top

50 responses to “jQuery Plugin Boilerplate”

Follow the comments via RSS
  • Zeno Rocha, 2011-05-17, 11:40

    Hey,

    I was thinking about translate this boilerplate to portuguese and also let other people to do that in their languages. I think Github is the perfect place to do that, why don’t you create a repository there?

    Reply
  • moiz, 2011-05-18, 12:46

    This may sound really like a newbie .. but i’m trying to write a plugin and this is wht i want to execute -

    $.Alerter({'message':'this is a test','onSuccess':function(data) { alert(data); } });
     

    The onSuccess is a callback function which – as you explained – is added to the defaults. My question is – how do i send the output to the onSuccess. I want to return back a True or False value after certain steps have been executed in the init()

    Thanks

    Reply
    • Stefan Gabos, 2011-05-18, 13:26

      it’s simple :) : after you generate the output (or whatever it may be that it should trigger the “onSuccess” event) simply call plugin.settings.onSucess()

  • Nicolas, 2011-06-06, 16:24

    Hi Stefan

    Thank you for the code. I have been using it in my plugins. What isn’t quite clear is this statement.

    element = element;

    Is this some sort of a hack?

    Reply
    • Stefan Gabos, 2011-06-06, 16:36

      no hacks there. it’s a redundant piece of code but it’s there to emphasize what’s what from that point on.

  • Brice, 2011-06-06, 23:00

    Hi Stephan,

    Thanks for your tutorial. I’am trying to use your exemple to make my pluging, but I have a problem with this part of the code

    $(this).data(‘pluginName’, plugin);. I don’t know why but this line is never call if I have an event call like this

    plugin.settings.onSucess() inside the init function.

    If I delete the event call, everything work correctly. Any idea ?

    Thanks a lot.

    Reply
  • Stefan Gabos, 2011-06-07, 04:20

    well…$(this).data(‘pluginName’, plugin) is run only once, when the plugin is created. $.fn.pluginName = function(options) { … } has to do with creating the plugin in the jQuery context and has nothing to do with how your plugin works. It simply tells jQuery that there is this plugin.

    Now, if you want to call plugin.settings.onSuccess() inside the init function, make sure you call it after plugin.settings = $.extend({}, defaults, options); Also, when you instantiate your plugin, you should have something like

    $(document).ready(function() {
        $('selector').pluginName({
            'foo': 'bar',
            onSuccess: function() {
                // code goes here
            }
        });
    });
    Reply
    • Brice, 2011-06-07, 07:28

      thanks for reply, i ‘ve done like you but if i try to get the data value (…. data(‘pluginName’) …. ) inside the onSuccess() function, i’ve an undefined object. That’s mean the plugin is not totally build.

      finaly i put the plugin in the return variable of the function :

      plugin.settings.onSuccess(plugin)
    • Stefan Gabos, 2011-06-07, 08:44

      it makes no sense to reference data(‘pluginName’) from *inside* the plugin that is for accessing the plugin from *outside* the plugin! from inside simply use “plugin” – just the way you correctly figured out.

      this is also stated in the comments:

      // plugin’s properties will be available through this object like:
      // plugin.settings.propertyName from inside the plugin or
      // element.data(‘pluginName’).settings.propertyName from
      // outside the plugin, where “element” is the
      // element the plugin is attached to;

  • Adam, 2011-06-10, 15:33

    Isn’t it common practice to include a semi-colon before any jQuery plugin definitions, to protect against incomplete objects, arrays, etc? Like so:

    ;(function($) { ...
    
    Reply
  • Burak Erdem, 2011-06-10, 22:40

    Great resource, thanks but please create a repository at Github and let us all fork that wonderful project.

    Reply
  • Tony Lea, 2011-06-11, 06:29

    Hi Stefan.

    Thanks so much for this boilerplate. I was looking for one when I created my first plug-in: http://www.tonylea.com/2011/jquery-illuminate/ From now on, I think I’ll use this template :)

    Thanks again.

    Reply
  • Vincent, 2011-06-12, 09:53

    In my opinion, it’s very sketchy to write “foo:’bar’”! Maybe it sounds “cool”, but this does not make your code very readable and not semantic!

    Reply
    • Stefan Gabos, 2011-06-12, 18:12

      “not semantic”? what do you mean? it is a very generic and a very common way of saying these kind of things. i could try “property: value”. does that sound ok?

  • maLakai, 2011-06-14, 13:40

    It looks good, except what Adam said (;) and I would rather move the defaults-extend to the $.fn.pluginName, so it is done once and available on that scope too.

    Reply
  • Manuel Meurer, 2011-06-18, 10:51

    Maybe rename foo_public_method to fooPublicMethod and foo_private_method to fooPrivateMethod for consistency? Otherwise, great scaffold!

    Reply
  • François Germain, 2011-06-23, 09:08

    Nice work ! Since now I’ll use it. I simply add the ability to call public method the old way :

    $.fn.pluginName = function(options) {
        var args = arguments;
        return this.each(function() {
            var i = $(this);
            if (undefined == (plugin = i.data('pluginName'))) {
                var plugin = new $.pluginName(this, options);
                i.data('pluginName', plugin);
            } else if (plugin[options]) {
                plugin[options].apply( plugin, Array.prototype.slice.call( args, 1 ));
            }
        });
    }
    /* ... */
    $('#element').data('pluginName').foo_public_method();
    $('#element').pluginName('foo_public_method');
    Reply
    • Stefan Gabos, 2011-06-23, 09:15

      good idea! thanks! i’ll add it at the next update

  • Antonio Trapani, 2011-06-29, 19:06

    Hey Stefan,
    nice code, this is so much better than previous boilerplate. I was wandering why did you put pluginName function in the $ scope instead of simply declaring it as

    function pluginName(element, options) {

    }

    Is there a clear reason?
    Thanks for your answer

    Reply
  • Stefan Gabos, 2011-06-29, 19:24

    Because this way you will be able to run the plugin without the need of specifically attaching it to an element; because it is name-spaced, you can’t just call “pluginName” in the global namespace. Therefore, it is only this way that we can run our plugin without attaching it to an element:

    $.pluginName()
    Reply
  • ionut, 2011-07-05, 18:41

    great article
    maybe you can expand on this with more examples
    i mean a more complex example of a plugin based on this using events etc (something like a file manager,image gallery)

    Reply
    • Stefan Gabos, 2011-07-05, 19:49

      see Zebra_Dialog, one of my jQuery plugins, that has events

Leave a Reply

Your email address will not be published
You can use <strong>, <em>, <a>, <img>, <code>
Characters are not case-sensitive