Question

I have a jQuery Plugin which accept multiple elements and some methods to be called like:

(function($){

  methods = {
    init : function( options, callbacks) {
      $.fn.myPlugin.settings = $.extend({
        'userDefinedMethod': function() {}
      }, options);

      return this.each(function(){
        $.fn.myPlugin.settings.userDefinedMethod();
      }
    }
  }

  $.fn.myPlugin = function(method) {
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exists on jQuery.myPlugin' );
    }
  }

})(jQuery);

An simple example which will make you understand what I want to achieve:

$(document).ready(function(){
  $('#myElement1, #myElement2, #myElement3').myPlugin({
    userDefinedMethod: function() {
      // I want here to use the elements in selector
      $(this).css('color', 'black');
    }
  });
});

I know that $(this) in the example above will represent the jQuery Plugin Object but I want somehow to use each element in the provided selector.

Was it helpful?

Solution

$(document).ready(function () {
    $('#myElement1, #myElement2, #myElement3').myPlugin({
        userDefinedMethod: function () {
            // I want here to use the elements in selector
            $(this).css('color', 'red');
        }
    });
});

(function ($) {

    methods = {
        init: function (options, callbacks) {
            //don't set the settings to shared object
            this.settings = $.extend({
                userDefinedMethod: $.noop
            }, options);

            return this.each($.proxy(function (idx, el) {
                //use Function.call() to set a custom execution context
                this.settings.userDefinedMethod.call(el);
            }, this))
        }
    }

    $.fn.myPlugin = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exists on jQuery.myPlugin');
        }
    }

})(jQuery);

Demo: Fiddle

OTHER TIPS

In methods.init function this will be the jQuery object obtained by quering the selector. So, if you want to send this to userDefinedMethod just use apply or call when you call that function:

...
var methods = {
    init : function( options, callbacks) {
      $.fn.myPlugin.settings = $.extend({
        'userDefinedMethod': function() {}
      }, options);

      $.fn.myPlugin.settings.userDefinedMethod.call(this);
      // or if you want to send the arguments
      // $.fn.myPlugin.settings.userDefinedMethod.apply(this, arguments);
      return this;
    }
}
...

Also, don't forget that you didn't use var for declaring methods. methods will become a magic global variable...

I also corrected the missing ) that was generating a syntax error.

JSFIDDLE

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top