Method for jQuery plugin - javascript

I'm trying to make a jQuery plugin for custom checkboxes and radio buttons.
(function($)
{
$.fn.checkboxRadio = function(options)
{
var defaults = some;
...
return this.each(function()
{
var button = $(this);
...
});
}
})(jQuery);
It can be used now by $('input').checkboxRadio(options);
How do I add a method check without changing current scope, to make a possible usage of something like $('input').checkboxRadio('check')?
How to handle a custom method and get its name inside my plugin?

Here is the official jquery plugin guide.
The part about wrapping functions is found here ("Plugin Methods") (the example is a would-be tooltip plugin) :
(function( $ ){
var methods = {
init : function(options) { ... },
show : function() { ... },
hide : function() { ... },
update : function(content) { ... }
};
$.fn.tooltip = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})(jQuery);
[update] explaining the methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )) line in the guide :
If you call $(selector).tooltip('update', 'hello') from your javascript code, you want to end up calling the update method, passing 'hello' as the content argument, with this set to $(selector) for the duration of the call.
That is what this line takes care of :
if method == 'update', methods[method] is the update method,
arguments will be equal to ['update', 'hello'], you have to drop the first element to get the arguments you want to pass to your method ; this is exactly what Array.prototype.slice.call(arguments, 1) does,
myFunc.apply(obj, argsArray) calls the function myFunc, passing argsArray as the arguments, and setting this to obj for the duration of the call.
So inside your methods, you can call this.each(...) to iterate over all of the selector's items, e.g. :
update: function(content) {
this.each(function(){ $(this).data('tooltip.content', content); });
return this;
}

You can connect plugin methods like this:
(function($) {
$.fn.checkboxRadio = function(options) {
var defaults = {
check: 'check'
}
return this.each(function() {
var o = options;
var _this = $(this);
if( o.check === 'check' ) {
_this.attr('checked','checked');
}else if ( o.check === 'uncheck' ) {
_this.removeAttr('checked');
}
});
}
})(jQuery);
and user document should be like what you want: $('input').checkboxRadio({check:'check'});

Related

append method to jquery plugin

i write this plugin and now i want add method to this plugin such as this
$.createMessage().removeMessage()
how can i do it?
my code is
$(function () {
$.extend({
createtext: function (options) {
var setting = {
holder: "",
text: "",
}
if (options != null) {
$.extend(setting, options)
}
var $this = $(setting.holder)
$this.find("div#CreatetextHolder").remove()
$this.append("<div id='CreatetextHolder'><span></span><p class='Createtext'>" + setting.text + "</p></div>")
$this.find("div#CreatetextHolder").fadeIn('slow')
}
})
})
thank you for your help
$(selector).createMessage().removeMessage() would require you to write two plugins - one for 'create' and the other for 'remove'.
It's far better to do everything in one plugin and you can do so by targeting the syntax ...
$(selector).createMessage('remove');
Then it's a matter of testing options in the plugin code, and branching accordingly.
Currently you test if (options != null) assuming options to be a javascript plain object and that the only action is initianisation.
But with my suggestion to allow $.createMessage('remove'), you need to perform more extensive testing/branching depending on what parameter(s) are actually passed.
For example:
$(function () {
$.extend({
createtext: function ( method, options ) {
var settings = {
holder: "",
text: ""
};
var methods = {
'init': function(options) {
var _settings = $.extend({}, settings, options);//this leaves `settings` unaffected and available for reuse in future inits.
//initialize here
},
'remove': function() {
//uninitialize here
}
}
// These tests allow `init' to be passed explicitly,
// or assumed if an options object is the only argument.
// Otherwise, a method such as 'remove' may be passed,
// with or without further parameters.
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || !method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist in jQuery.createtext');
}
}
});
});

How to call elements inside user defined methods of an jQuery plugin

I have a jQuery Plugin which accept multiple elements and some methods to be called like:
(function($){
methods = {
init : function( options, callbacks) {
$.fn.myPlugin.settings = $.extend({
'userDefinedMethod': function() {}
}, options);
return this.each(function(){
$.fn.myPlugin.settings.userDefinedMethod();
}
}
}
$.fn.myPlugin = function(method) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exists on jQuery.myPlugin' );
}
}
})(jQuery);
An simple example which will make you understand what I want to achieve:
$(document).ready(function(){
$('#myElement1, #myElement2, #myElement3').myPlugin({
userDefinedMethod: function() {
// I want here to use the elements in selector
$(this).css('color', 'black');
}
});
});
I know that $(this) in the example above will represent the jQuery Plugin Object but I want somehow to use each element in the provided selector.
$(document).ready(function () {
$('#myElement1, #myElement2, #myElement3').myPlugin({
userDefinedMethod: function () {
// I want here to use the elements in selector
$(this).css('color', 'red');
}
});
});
(function ($) {
methods = {
init: function (options, callbacks) {
//don't set the settings to shared object
this.settings = $.extend({
userDefinedMethod: $.noop
}, options);
return this.each($.proxy(function (idx, el) {
//use Function.call() to set a custom execution context
this.settings.userDefinedMethod.call(el);
}, this))
}
}
$.fn.myPlugin = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exists on jQuery.myPlugin');
}
}
})(jQuery);
Demo: Fiddle
In methods.init function this will be the jQuery object obtained by quering the selector. So, if you want to send this to userDefinedMethod just use apply or call when you call that function:
...
var methods = {
init : function( options, callbacks) {
$.fn.myPlugin.settings = $.extend({
'userDefinedMethod': function() {}
}, options);
$.fn.myPlugin.settings.userDefinedMethod.call(this);
// or if you want to send the arguments
// $.fn.myPlugin.settings.userDefinedMethod.apply(this, arguments);
return this;
}
}
...
Also, don't forget that you didn't use var for declaring methods. methods will become a magic global variable...
I also corrected the missing ) that was generating a syntax error.
JSFIDDLE

jquery plugin that returns a new object

I'm creating my first jQuery plugin and want to create the jQuery object, but want to be able to control the object that was just created...
I'm building my plugin following the format recommended here: http://docs.jquery.com/Plugins/Authoring
Here is my test code:
(function($){
var $this = $(this);
var methods = {
init : function( options ) {
// methods.createDiv();
$this = $('<div>TEST CONTENT</div>')
.attr({ 'id':'test' })
.css({'color':'white','backgroundColor': 'red'})
.appendTo("body");
setTimeout(function(){
methods.green();
},
3000
);
return $this;
},
green : function( ) {
$this.css({'backgroundColor': 'green'});
},
blue : function( ) {
$this.css({'backgroundColor': 'blue'});
}
};
$.fn.myPlugin = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
$(document).ready(function () {
var myTest = $.fn.myPlugin();
myTest.blue();
});
Ultimately, I want to be able to control the newly created div using the myTest variable, but it's not working. I'm sure there are obvious pieces I'm missing and mistakes I'm making, but that's why I'm posting here. It's my first plugin, so if anyone could help me get this test code up and running I'd appreciate it. Currently, firebug report: "TypeError: myTest.blue is not a function"
Invoke your method as:
myTest.myPlugin("blue");
Here is a demo: http://jsfiddle.net/5p2Ba/
blue is not a method of the jQuery object here. You are only binding the methods object into a module using a closure.

jQuery .data() and plugins

I am trying to use jQuery's .data() tool in a jQuery plugin but I'm getting some odd results.
Here is a cut down version of my plugin with the relevant code:
(function( $ ){
var methods = {
init : function( options ) {
// Do some stuff
this.data('name', 'New Component');
return this;
},
getStateData : function () {
// Function returns all data for save
var state = new Object;
state.name = this.data('name');
// snip ... Add some other bits to state
// ...
return state;
},
setStateData: function (args) {
var key = args[0];
var value = args[1];
// snip
this.data(key, value);
}
};
$.fn.component7Segment = function(method) {
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.designComponent' );
}
};
})( jQuery );
If I call $(instance-of-plugin).component7Segment('getStateData'); the plugin returns the correct 'name' however if I call setStateData to change the name it has not changed the 'name' value when I next call getStateData.
Doing console.log(this); in each function looks slightly different so I started trying:
$.data($('#object-id'), 'name', value);
This still doesn't have the desired effect.
Can anybody see what I am missing?
Assuming you're calling setStateData like this:
$(instance).component7Segment("setStateData", "name", "Foo");
the setStateData function should be changed to look like this:
setStateData: function () {
var key = arguments[0];
var value = arguments[1];
// snip
this.data(key, value);
}
Note the removal of the args parameter and the use of the special arguments array-like object instead.
Example: http://jsfiddle.net/andrewwhitaker/ShFHC/
Your original problem was most likely that you were calling setStateData with parameters name and "foo". args[0] and args[1] was actually accessing the characters in name at that position instead of the arguments passed to the function.

Trying to learn jQuery plugin development

So I'm trying to learn how to implement method collection for a plugin based on this example: http://docs.jquery.com/Plugins/Authoring
What I cannot understand is how options that are extended with defaults for the plugin get sent to the individual methods.
I'm pretty sure any original options get sent to the method here:
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
So how can you extend these arguments with defaults? The example doesn't really define how to do this...
var methods = {
init : function( options ) {
return this.each(function(){
$(window).bind('resize.tooltip', methods.reposition);
});
}
}
Also, here is the code from the example plugin authoring page:
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
$(window).bind('resize.tooltip', methods.reposition);
});
},
destroy : function( ) {
return this.each(function(){
$(window).unbind('.tooltip');
})
},
reposition : function( ) { // ... },
show : function( ) { // ... },
hide : function( ) { // ... },
update : function( content ) { // ...}
};
$.fn.tooltip = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
Looks like my previous answer was closer to the mark than I previously thought.
Yes, this line is passing on the arguments:
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
Using .apply(), you can call a method, change its context (this value), and give it a collection of arguments instead of individual ones. Handy if you don't know how may arguments need to be passed on.
So you can break the above line down like this:
// reference the arguments passed to the plugin
var args = arguments;
// eliminate the first one, since we know that's just the name of the method
args = Array.prototype.slice.call( arguments, 1 )
// call the method that was passed,
// passing along the Array of the arguments (minus the first one),
return methods[method].apply( this, args);
// Note that it is being called from the context of "this" which is the jQuery object
So if the plugin was called like this:
$('.someElem').tooltip('destroy', 'someArg', 'anotherArg' );
The code will locate the "destroy" method, slice "destroy" off of the Arguments object, and call "destroy" passing along the Array of remaining arguments.
you use $.extend(existingObject || {} (new object), oneObject, secondObject, nthObject)
var mydefaults = { myDefaultArg : "foo" }
var inputOptions = { myDefaultArg : "Somethin else" }
var options = $.extend({}, mydefaults, inputOptions);
options.myDefaultArg == "Somethin else";
To access data, or to save them,you can use the data method
so if you are in the plugin, "this" is the jquery element element, you can now save data into it.
$(this).data("pluginname.somedataname", data);
and retriev it
var data = $(this).data("pluginname.somedataname");

Categories