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\$
  • \$\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 Jul 3 '12 at 15:17
  • \$\begingroup\$ Oh, that's a typo, that should be Object.create(PluginClass). I'll edit \$\endgroup\$ – jackwanders Jul 3 '12 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 Jul 7 '12 at 10:35
  • 1
    \$\begingroup\$ As you're writing boiler you should follow the jQuery style guide's directions on spacing \$\endgroup\$ – megawac Feb 3 '14 at 15:54
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, privacy policy and cookie policy

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