How do I create a jQuery plugin so that I can use namespaces in my plugin ?
$(\"#id1\").amtec.foo1();
$(\"#id1\").amtec.foo2();
None of th
$.cg = {
foo1: function(weq){
return console.log(weq);
},
foo2: function(rw){
return console.log(rw);
}
};
$.cg = { // will result in error because $.cg is already declared above
foo4: function(rw){ // will result in error
return console.log(rw); // will result in error
} // will result in error
}; // will result in error
$.cg.foo3 = function(weq){ //to add anything new to $.cg , you have to do it this way.
return console.log(weq);
}
$.cg.foo1("12");
$.cg.foo2("22"); //works fine.
$.cg.foo3("112"); //works fine.
(function($){
$.namespace = function(ns, functions){
$.fn[ns] = function() {return this.extend(functions)};
};
$.namespace('$', $.fn); // the default namespace
})(jQuery);
So now you can have a plugin:
$.fn.func = function(){alert('plugin'); return this'};
and create plugins in a namespace:
$.namespace ('mynamespace', {
func: function() {alert('namespaced plugin'); return this;},
otherfunc: function() {return this.css('color', 'yellow');}
});
And if you do
$('div').func(); // alerts 'plugin' -- no namespace
But
$('div').mynamespace().func(); // alerts 'namespaced plugin'
And
$('div').mynamespace().func().$().func(); // alerts 'namespaced
plugin', then resets to the normal jquery and alerts 'plugin'
I know I'm almost three years late to the party, but hopefully future readers of this question can benefit from my answer. The answer by GSto looks great from a jQuery plugin design standpoint, but has one small issue: calling mynamespace()
clobbers the returned jQuery instance with new methods. Here is an example of that being an issue:
$myDiv = $('.mydiv');
$myDiv.mynamespace().height(); // this will be `height' from mynamespace
$myDiv.height(); // this will STILL be `height' from mynamespace
// because it has overwritten $myDiv.height
The chosen answer does not have this issue because there amtec()
is not a jQuery instance and is instead an object that calls its methods with the jQuery instance as context. I have taken concepts from both answers and written the namespace plugin below:
(function($) {
$.namespace = function(namespaceName, closures) {
if ($.fn[namespaceName] === undefined) {
$.fn[namespaceName] = function executor(context) {
if (this instanceof executor) {
this.__context__ = context;
}
else {
return new executor(this);
}
};
}
$.each(closures, function(closureName, closure) {
$.fn[namespaceName].prototype[closureName] = function() {
return closure.apply(this.__context__, arguments);
};
});
};
})(jQuery);
Example usage:
$.namespace('milosz', {
redify: function() {
$(this).css('color', '#ff0000');
},
greenify: function() {
$(this).css('color', '#00ff00');
}
});
$.namespace('milosz', {
blueify: function() {
$(this).css('color', '#0000ff');
}
});
$('.mydiv').milosz().redify(); // The HTML elements with class `mydiv' are now red
The code uses some pretty low-level details of JavaScript that are well-explained by John Resig's Advanced JavaScript tutorial, but loosely speaking what is happening in the example is this:
When milosz
(internally $.fn[namespaceName]
) is called, this
points to the jQuery
instance returned by $('.mydiv')
. Hence, the if
statement falls through to the else
block and the constructor version of milosz
is called (referred-to internally as executor
for reasons that are about to become apparent). The constructor is passed a single parameter: this
, a pointer to the jQuery
the instance that is going to be the execution context for all members of the milosz
namespace. We enter back into the if
statement, this time executing the first block, wherein the passed-in jQuery
instance is stored in a member variable called __context__
(which hopefully has a low chance of being overwritten). The constructed object is returned, complete with a reference to the original jQuery
instance and any wrappers added to its prototype by invocations of $.namespace
. These wrappers simply execute the methods passed into the milosz
namespace with the original jQuery
object as context, as happens when redify
is executed.
Bah, I know it's a mouthful, anyway the point is it works like the accepted answer but looks like the jQueryish answer, which to me is the best of both worlds.
(function($) {
$.fn.amtec = function () {
var jq = this;
return {
foo1: function(){
return jq.each(function(){});
},
foo2: function(){
return jq.each(function(){});
}
}
};
})(jQuery);
I know it's an old question... But why write all this extra code when you can just replace .
with _
?
$.fn.amtec_foo1 = function(){ return this.each(function(){}); }
$.fn.amtec_foo2 = function(){ return this.each(function(){}); }
Better yet, give your plugin a name that's original & project agnostic.
$.fn.fooize = function(){ return this.html('Element has been Fooized!'); }