javascriptjqueryjquery-pluginsjavascript-framework

How to create a jQuery plugin with methods?


I'm trying to write a jQuery plugin that will provide additional functions/methods to the object that calls it. All the tutorials I read online (have been browsing for the past 2 hours) include, at the most, how to add options, but not additional functions.

Here's what I am looking to do:

//format div to be a message container by calling the plugin for that div

$("#mydiv").messagePlugin();
$("#mydiv").messagePlugin().saySomething("hello");

or something along those lines. Here's what it boils down to: I call the plugin, then I call a function associated with that plugin. I can't seem to find a way to do this, and I've seen many plugins do it before.

Here's what I have so far for the plugin:

jQuery.fn.messagePlugin = function() {
  return this.each(function(){
    alert(this);
  });

  //i tried to do this, but it does not seem to work
  jQuery.fn.messagePlugin.saySomething = function(message){
    $(this).html(message);
  }
};

How can I achieve something like that?

Thank you!


Update Nov 18, 2013: I've changed the correct answer to that of Hari's following comments and upvotes.


Solution

  • According to the jQuery Plugin Authoring page (http://docs.jquery.com/Plugins/Authoring), it's best not to muddy up the jQuery and jQuery.fn namespaces. They suggest this method:

    (function( $ ){
    
        var methods = {
            init : function(options) {
    
            },
            show : function( ) {    },// IS
            hide : function( ) {  },// GOOD
            update : function( content ) {  }// !!!
        };
    
        $.fn.tooltip = function(methodOrOptions) {
            if ( methods[methodOrOptions] ) {
                return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
            } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
                // Default to "init"
                return methods.init.apply( this, arguments );
            } else {
                $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.tooltip' );
            }    
        };
    
    
    })( jQuery );
    

    Basically you store your functions in an array (scoped to the wrapping function) and check for an entry if the parameter passed is a string, reverting to a default method ("init" here) if the parameter is an object (or null).

    Then you can call the methods like so...

    $('div').tooltip(); // calls the init method
    $('div').tooltip({  // calls the init method
      foo : 'bar'
    });
    $('div').tooltip('hide'); // calls the hide method
    $('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method
    

    Javascripts "arguments" variable is an array of all the arguments passed so it works with arbitrary lengths of function parameters.