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.
You can do:
In this way your plugins object is stored as data value in your element.
Here i want to suggest steps to create simple plugin with arguments.
JS
Here, we have added default object called
params
and set default values of options usingextend
function. Hence, If we pass blank argument then it will set default values instead otherwise it will set.HTML
Read more: How to Create JQuery plugin
Here is my bare-bones version of this. Similar to the ones posted before, you would call like:
-or access the instance directly @
plugin_MessagePlugin
MessagePlugin.js
This can actually be made to work in a "nice" way using
defineProperty
. Where "nice" means without having to use()
to get plugin namespace nor having to pass function name by string.Compatibility nit:
defineProperty
doesn't work in ancient browsers such as IE8 and below. Caveat:$.fn.color.blue.apply(foo, args)
won't work, you need to usefoo.color.blue.apply(foo, args)
.JSFiddle link
The problem with the currently selected answer is that you're not actually creating a new instance of the custom plugin for every element in the selector like you think you're doing... you're actually only creating a single instance and passing in the selector itself as the scope.
View this fiddle for a deeper explanation.
Instead, you'll need to loop through the selector using jQuery.each and instantiate a new instance of the custom plugin for every element in the selector.
Here's how:
And a working fiddle.
You'll notice how in the first fiddle, all divs are always moved to the right the exact same number of pixels. That is because only one options object exists for all elements in the selector.
Using the technique written above, you'll notice that in the second fiddle, each div is not aligned and is randomly moved (excluding the first div as it's randomizer is always set to 1 on line 89). That is because we are now properly instantiating a new custom plugin instance for every element in the selector. Every element has its own options object and is not saved in the selector, but in the instance of the custom plugin itself.
This means that you'll be able to access the methods of the custom plugin instantiated on a specific element in the DOM from new jQuery selectors and aren't forced to cache them, as you would be in the first fiddle.
For example, this would return an array of all options objects using the technique in the second fiddle. It would return undefined in the first.
This is how you would have to access the options object in the first fiddle, and would only return a single object, not an array of them:
I'd suggest using the technique above, not the one from the currently selected answer.
I got it from jQuery Plugin Boilerplate
Also described in jQuery Plugin Boilerplate, reprise