Alex
Alex

Reputation: 68096

How to make a function variable be called like jquery plugins?

Plugin:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var mymethod = function(){
      // I want to be able to access "this" here ('.element')

      return this; 
    };

    return this.each(function() {        
      // $('.element', this).mymethod(); <- how to do this?
    });

  };
})( jQuery );

I want to call mymethod like this:

$('.element').mymethod();

Is this possible?

Basically it needs to keep the chaining so I can further call other functions...

Upvotes: 0

Views: 380

Answers (5)

whitneyit
whitneyit

Reputation: 1226

If you haven't already done so, I would highly recommend checking out the jQuery plugin authoring page. http://docs.jquery.com/Plugins/Authoring

The best way to call a specific method would be by going

$( '#foo' ).myPlugin( 'myMethod' );

The way you would achieve something like that would be like this, ( note: all taken from the jQuery plugin authoring site )

( function ( $ ) {

    var methods = {
        init : function( options ) {

            // Init function here

        },
        destroy : function( ) {

            // Teardown function here

        }
    };

    $.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 exist on jQuery.myPlugin' );
}    


};

})( jQuery );

Upvotes: 2

qwertymk
qwertymk

Reputation: 35284

Close, you just lose the this keyword whenever there's a new function keyword. Try saving it first:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var that = this;

    var mymethod = function(_this, dotElem){
      // I want to be able to access "this" here ('.element')
        that.hide().blah()...

      return this; // this isn't needed as we are going to anyway return `this.each()`
    };

    return this.each(function() {        
        mymethod(this, $('.element' )); <- how to do this?
    });

  };
})( jQuery );

Upvotes: 2

Matt Lo
Matt Lo

Reputation: 5731

Alter MyMethod so its a direct extension

$.fn.mymethod = function() {
   this.hide(); // the .element
   return this; // continue the daisy chain
}

// example usage
$(document).ready(function() {
   $("div").mymethod();
});

Updated x2 (had a typo)!

http://jsfiddle.net/MattLo/2TWMV/1/

Upvotes: 1

Daff
Daff

Reputation: 44215

If you want to call it like a jQuery plugin you will have no way around adding it to the jQuery prototype ($.fn). But if you just want to have this reference the jQuery element of your selector you can just use apply:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var mymethod = function(){
      // I want to be able to access "this" here ('.element')

      return this; 
    };

    return this.each(function() {        
      mymethod.apply($('.element', this));
    });

  };
})( jQuery );

Upvotes: 2

James M
James M

Reputation: 16718

Well, then you'd just do:

$.fn.mymethod = function () { ...   return this; }

jQuery will automatically pass the element it's called on as this.

But it's considered bad practice to add lots of functions this way. That's why most plugins just add one function to $.fn and take a string argument for which method to call.

Upvotes: 1

Related Questions