views:

349

answers:

3

I'm creating a jQuery plugin that that is rather large in scope. In fact, the plugin technically consists of a few plugins that all work together.

(function($){
    $.fn.foo = function(){
        //plugin part A
    }
    $.fn.bar = function(){
        //plugin part B
    }
    $.fn.baz = function(){
        //plugin part C
    }
}(jQuery))

Is it possible to namespace jQuery plugins such that the minor plugins could be functions of the larger plugin

$.fn.foo.bar = function(){}
$.fn.foo.baz = funciton(){}

This would keep from polluting the jQuery function namespace. You could then call the plugins like

$('#example').foo()
$('#other_example').foo.bar()

The issue I have run into when trying this out myself is that the functions declared as properties of the foo() plugin function don't have their references to 'this' set properly. 'this' ends up referring to the parent object and not the jQuery object.

Any ideas or opinions would be appreciated.

-Matt

A: 

Well, I'm sure there are many ways to skin this cat. The jQuery UI library uses a pattern like this:

// initialize a dialog window from an element:
$('#selector').dialog({});

// call the show method of a dialog:
$('#selector').dialog('show');
Ken Browning
Personally, I believe this way to be a "dirty" hack due to the fact that they couldn't use $('#selector').dialog().show(), but it is an alternative way to do it.
Tres
+8  A: 

As soon as you use $.fn.foo.bar() "this" points to "foo", which is what you would expect in javascript (this being the object that owns the function.)

I have noticed in plugins from jQuery UI (like sortable) where you call functions like:

$(...).sortable("serialize");
$(...).sortable({options});

If you were doing something like this - you could extend jQuery itself:

$.foo_plugin = {
  bar: function() {},
  baz: function() {}
}

$.fn.foo = function(opts) {
  if (opts == 'bar') return $.foo_plugin.bar.call(this);
  if (opts == 'baz') return $.foo_plugin.baz.call(this);
}
gnarf
I had never looked at the jQuery UI library before. But that is a very interesting and applicable solution. Thanks.
mazniak
+2  A: 

I know this has already been answered but I have created a plugin that does exactly what you want:

http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js

I've included a small example below, but check out this jQuery Dev Group post for a more in-depth example: http://groups.google.com/group/jquery-dev/browse_thread/thread/664cb89b43ccb92c/72cf730045d4333a?hl=en&q=structure+plugin+authoring#72cf730045d4333a

It allows you to create an object with as many methods as you want:

var _myPlugin = function() {
    // return the plugin namespace
    return this;
}

_myPlugin.prototype.alertHtml = function() {
    // use this the same way you would with jQuery
    alert($(this).html());
}

$.fn.plugin.add('myPlugin', _myPlugin);

now you can go:

$(someElement).myPlugin().alertHtml();

There are, of course, many, many other possibilities with this as explained in the dev group post.

Tres