2
\$\begingroup\$

I've been writing some smaller jQuery plugins lately, and I've been thinking of writing up some boilerplate that I can use when writing new ones. I have code that works (for now), but I want to share it and get feedback on things I may be missing as I move to larger plugins.

/**
*  jQuery Plugin Boilerplate
*  - find and replace the following variable names
*    - utilities   : namespace for shared utility functions
*    - PluginClass : class name for plugin object
*    - pluginName  : the name of your plugin function, e.g. $('.foo').myPlugin()
**/
(function($) {

    /**
    *  Utility function object
    *  - namespace wrapper for variables or functions shared between all plugin instances
    **/
    var utilities = {

        // example utility function
        getInt: function(i) {
            i = parseInt(i, 10);
            return isNaN(i) ? 0 : i;
        }

    },

    /**
    *  Main plugin class
    *  - encapsulate each instance of plugin as an object
    **/
    PluginClass = {

        // other instance-specific functions get defined here

        init: function(el,options) {
            var _t = this;  // for maintaining reference to plugin class in callbacks

            this.options = $.extend({}, $.fn.pluginName.defaults, options);
            this.el = el;
            this.$el = $(el);

            // do your plugin stuff
        },

        callFn: function(fn) {
            switch(fn) {
              // case statements matching allowable function aliases
              // which execute the appropriate plugin functions
            }
        }

    };

    /**
    *  Plugin function
    *  - for each element passed to the plugin, create a new class instance
    **/
    $.fn.pluginName = function () {
        var arg = arguments[0];
        var fn, options;

        // if the argument passed is a string, then the user
        // is calling a function. Otherwise, it's an options object
        if(typeof arg === 'string') { 
            fn = arg; 
        }
        else {
            options = arg;
        }

        if (this.length > 0) {
            return this.each(function(i) {
                var el = $(this), p;

                // if plugin instance already exists, use it
                if(el.data('pluginName')) {
                    p = el.data('pluginName');
                    if(fn) { p.callFn(fn); }
                    else { p.init(this,options); }
                } else {
                    p = Object.create(PluginClass);
                    el.data('pluginName', p);
                    p.init(this,options);
                }
            });
        }

    };

    /**
    *  Plugin default options
    *  - created outside of plugin function for easier overriding by user
    **/
    $.fn.pluginName.defaults = {
        some: thing,
        foo: 'bar'
    };

})(jQuery);​

Here's an example I created using this boilerplate. It's nothing fancy, it simply takes the text of an element and paints each character with a different color.

jQuery Plugin Demo - $.paintText()

My main concern here is with the functionality of using $('#foo').paintText('fnAlias') to call a function on an existing plugin instance. My way seems to work, but part of me feels there may be a more efficient way.

Thanks for any help.

\$\endgroup\$
4
  • \$\begingroup\$ Do you mean p = new PluginClass.init(this,options)? You can't new the PluginClass itself because it's not a function. \$\endgroup\$
    – Esailija
    Commented Jul 3, 2012 at 15:17
  • \$\begingroup\$ Oh, that's a typo, that should be Object.create(PluginClass). I'll edit \$\endgroup\$ Commented Jul 3, 2012 at 15:23
  • \$\begingroup\$ If you haven't come across this one, there is already a jQuery boilerplate that I tend to use when making plugins. \$\endgroup\$
    – Joseph
    Commented Jul 7, 2012 at 10:35
  • 1
    \$\begingroup\$ As you're writing boiler you should follow the jQuery style guide's directions on spacing \$\endgroup\$
    – megawac
    Commented Feb 3, 2014 at 15:54

1 Answer 1

2
\$\begingroup\$

From a once over:

  • I like how you store both el and $el
  • I also like how you expose your defaults
  • Not sure about _t, I think generally self is considered to a better name for this
  • You should have a spot in your boilerplate to define the prototype of your plugin class
  • Lint finds nothing worth mentioning
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.