javascriptjqueryjquery-pluginsprivileged-functions

Is it possible to write a second non-static, selecting, priviledged function in a JQuery Plugin?


Almost all of the examples in the jQuery tutorials that I've read, usually use one major public function for their selecting plugin. When I say 'selecting' plugin, I mean one that is not simply a static function extended onto jQuery.

For example:

(function($) {

jQuery.fn.actionList = function(options) {
    var opts = $.extend({}, $.fn.actionList.defaults, options);
    return this.each(function(){
       alert(this);
    });

};

$.fn.actionList.defaults = {
    listHtml: '<div>Set the list html</div>'
};

})(jQuery);

but not:

jQuery.log = function(message) {
  if(window.console) {
     console.debug(message);
  } else {
     alert(message);
  }
};

This works fine for most things, but what I would like to do is be able to call a second function on the object returned from the first call.

var actionBox = $('actionBox').actionList(options);

//Many light-cycles later

actionBox.refreshData(data);

or maybe even:

$('actionBox').actionList(options);

// laaateerr

$('actionBox').actionList.refreshData(data);

I'm guessing one or both of these is not possible or, at least not advisable, but I'm only now getting into the deepest aspects of jQuery and javascript.

Could someone explain how to do this, or if it's not possible or advisable, why? and what they would do instead?

Thanks for reading!


Solution

  • I'm not quite sure what you're getting at, but you can call a second function on the object returned from the first function - in fact, it is very much encouraged to return a jQuery object from your plugins, and the reason why you can chain commands in jQuery.

    Using your examples

    var actionBox = $('actionBox').actionList(options);
    
    //Many light-cycles later
    
    actionBox.refreshData(data);
    

    would work fine, so long as both .actionList() and .refreshData(data) commands both return a jQuery object.

    And

    $('actionBox').actionList.refreshData(data);
    

    would need to be

    $('actionBox').actionList().refreshData(data);
    

    EDIT:

    Looking at the jQuery source code,

    jQuery.fn = jQuery.prototype = { 
        /* 
            Load of 'property' functions of jQuery object... 
        */ 
    }
    

    so, adding properties (a.k.a plugins) to jQuery.fn extends the prototype of the jQuery object. When you call

    $(selector, context);
    

    a new jQuery object is returned, using the init property function of the jQuery object

    jQuery = window.jQuery = window.$ = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context );
    },