Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Plugin Namespacing Functions

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

like image 642
mazniak Avatar asked Aug 02 '09 19:08

mazniak


3 Answers

As soon as you use $.fn.foo.bar() -- this points to $.fn.foo, which is what you would expect in JavaScript (this being the object that the function is called on.)

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);
}
like image 194
gnarf Avatar answered Nov 15 '22 15:11

gnarf


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.

like image 22
Tres Avatar answered Nov 15 '22 17:11

Tres


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');
like image 43
Ken Browning Avatar answered Nov 15 '22 17:11

Ken Browning