27-09-2011

jQuery plugin patterns jQuery

Below are some very useful design patterns for coding jQuery plugins.

Source: https://gist.github.com/1184226

 
 
/*
**********************************************************
Plugin boilerplate from @ajpiano with a minor adjustment.
**********************************************************
*/
 
;(function ($, undefined) {
 
    // Create the defaults, only once!
    var defaults = {
        propertyName: "value"
    };
 
    // The actual plugin constructor
    function Plugin(element, options) {
        this.element = element;
        this.options = $.extend({}, defaults, this.options);
        this.init();
    }
 
    Plugin.prototype.init = function () {
        // Place initialization logic here
        // You already have access to the DOM element and the options via the instance,
        // e.g., this.element and this.options
    };
 
    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn.plugin = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin")) {
                $.data(this, "plugin", new Plugin(this, options));
            }
        });
    }
 
})(jQuery);
 
 
/*
**********************************************************
A distilled template based on @cowboys jQuery pluginization
'best options' tip where options can be overridden both globally
and per-call. Thanks to @mathias for reminding me about the
pattern.
**********************************************************
*/
 
(function ($, undefined) {
    $.fn.pluginName = function (options) {
        // Override defaults with specified options.
        options = $.extend({}, $.fn.pluginName.options, options);
        return this.each(function () {
            var elem = $(this);
        });
    };
    // Some sensible defaults.
    $.fn.pluginName.options = {
        key: "value",
        myMethod: function (elem, param) {}
    };
})(jQuery);
 
 
/*
*******************************************************
jQueryUI 1.8/9 Widget boilerplate from @addyosmani
with input from @peolanha
*******************************************************
*/
 
 
(function ($, window, document, undefined) {
 
    $.widget("demo.myComponent", {
 
        //Options to be used as defaults
        options: {
            someValue: null
        },
 
        //Setup widget (eg. element creation, apply theming, bind events etc.)
        _create: function () {
            //this.element.addStuff();
        },
 
        //Destroy an instantiated plugin and clean-up modifications the widget has made to the DOM
        destroy: function () {
            //this.element.removeStuff();
            // For UI 1.8, destroy must be invoked from the base widget
            $.Widget.prototype.destroy.call(this);
            // For UI 1.9, define _destroy instead and don't worry about calling the base widget
        },
 
        methodB: function (event) {
            //_trigger dispatches callbacks the plugin user can subscribe to
            //signature: _trigger(type, event, objectOfKeyValuePairsToPassToCallback)
            this._trigger('methodA', event, {
                key: value
            });
        },
 
        methodA: function (event) {
            this._trigger('dataChanged', event, {
                key: value
            });
        },
 
        //Respond to any changes the user makes to the option method
        _setOption: function (key, value) {
            switch (key) {
            case "someValue":
                //this.options.someValue = doSomethingWith( value );
                break;
            default:
                //this.options[ key ] = value;
                break;
            }
 
            // For UI 1.8, _setOption must be manually invoked from the base widget
            $.Widget.prototype._setOption.apply(this, arguments);
            // For UI 1.9 the _super method can be used instead
            //this._super( "_setOption", key, value );
        }
    });
 
})(jQuery, window, document);
 
/*
****************************************************************
jQuery plugin skeleton using extend pattern
by @oscargodson with input from @timmywil
note: needs comments
****************************************************************
*/
 
;(function($){
    $.fn.extend({
        pluginname: function(options) {
            this.defaultOptions = {};
            var settings = $.extend({}, this.defaultOptions, options);
            return this.each(function() {
                var $this = $(this);
            });
        }
    });
})(jQuery);
 
 
/*
**************************************************************
jQueryUI 1.8 widget pattern demonstrating custom event pub/sub
fore more info read: http://bit.ly/cKAmDa
 
Use jQuery’s custom events to enable publish/speak and subscribe/
listen into widgets. Each widget would publish certain events and
subscribe to others. This approach effectively decouples the widgets
and allows them to function independently.
 
note from addy: if you would prefer to use pub/sub here instead
you can either implement something lightweight based on ben alman's
pub/sub or use a mediator to publish/subscribe instead.
**************************************************************
*/
 
(function(){
    $.widget("ui.ajaxStatus", {
        options: {
 
        },
        _create : function() {
            var self = this;
 
            self.element.addClass("dpui-widget")
            self.element.bind("dpui:ajaxStart", function(e) {
                console.log("ajax start");
            });
 
            self.element.bind("dpui:ajaxEnd", function(e) {
                console.log("ajax end");
            });
        },
        destroy: function(){
            $.Widget.prototype.destroy.apply(this, arguments);
        },
    });
});
 
//usage: $(".dpui-widget").trigger("dpui:ajaxStart");
 
 
/*
***********************************************
Namespaced Starter Template from @dougneiner
***********************************************
*/
(function ($) {
    if (!$.myNamespace) {
        $.myNamespace = new Object();
    };
 
    $.myNamespace.myPluginName = function (el, myFunctionParam, options) {
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;
 
        // Access to jQuery and DOM versions of element
        base.$el = $(el);
        base.el = el;
 
        // Add a reverse reference to the DOM object
        base.$el.data("myNamespace.myPluginName", base);
 
        base.init = function () {
            base.myFunctionParam = myFunctionParam;
 
            base.options = $.extend({}, $.myNamespace.myPluginName.defaultOptions, options);
 
            // Put your initialization code here
        };
 
        // Sample Function, Uncomment to use
        // base.functionName = function(paramaters){
        //
        // };
        // Run initializer
        base.init();
    };
 
    $.myNamespace.myPluginName.defaultOptions = {
        myDefaultValue: ""
    };
 
    $.fn.mynamespace_myPluginName = function (myFunctionParam, options) {
        return this.each(function () {
            (new $.myNamespace.myPluginName(this, myFunctionParam, options));
        });
    };
 
})(jQuery);
 
 
 
/*
***************************************************************
A lite (non jQueryUI) widget pattern for plugins from @cowboy
***************************************************************
*/
 
/*!
* jQuery simpleWidget - v0.1pre - 10/28/2010
* http://benalman.com/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
 
(function($,undefined){
  '$:nomunge'; // Used by YUI compressor.
 
  $.simpleWidget = function( widget_name, widget ) {
 
    // Create selector.
    $.expr[':'][ widget_name ] = function( elem ) {
      return !!$.data( elem, widget_name );
    };
 
    // Create plugin method.
    $.fn[ widget_name ] = function( options ) {
      var args,
        args_to_slice = 0,
        method_name = '_create',
        result;
 
      // Was a method name passed as the first argument?
      if ( typeof options === 'string' && $.isFunction( widget[ options ] ) ) {
        method_name = options;
        args_to_slice = 1;
      }
 
      // Parse the passed arguments.
      args = Array.prototype.slice.call( arguments, args_to_slice );
 
      // Call the appropriate method in the context of each passed element's
      // instance.
      this.each(function(){
        var elem = $(this),
          data = elem.data( widget_name ),
          created = data,
          method;
 
        // If widget has no data, initialize instance data.
        data || elem.data( widget_name, data = $.extend( {}, widget, {
          element: elem,
          options: options
        }));
 
        // Only execute method when appropriate.
        if ( created ? method_name !== '_create' : method_name !== 'destroy' ) {
          method = data[ method_name ];
          result = $.isFunction( method ) && method.apply( data, args );
        }
 
        if ( method_name === 'destroy' ) {
          // If destroying a widget, remove instance data.
          elem.removeData( widget_name );
 
        } else if ( result !== undefined ) {
          // If method returned a non-undefined value, break out of the each.
          return false;
        }
      });
 
      // If method returned a non-undefined value, return that value (this will
      // break the chain).
      return result !== undefined ? result : this;
    };
  };
 
})(jQuery);
 
 
/*
***********************************************
Light plugin with public/private methods from @cowboy
***********************************************
*/
(function($){
 
  var private_var;
 
  $.myNS = {
    public_method1: function(){
      private_method();
    },
    public_method2: function(){
      return private_var;
    }
  };
 
  function private_method() {
    $.myNS.public_method2();
  }
 
})(jQuery);

Comments:

Your comment:

»

 

[x]