Reputation: 1643
I wrote a jq-plugin where I first want to init the selected elements (all of them-each). Later in the code I want to get a string produced by a method. But all it returns are the objects but not my string.
i did a lot of research on the internet but i don't know how to make the plugin 'chainable' on the one hand and 'returning any values' on the other hand.
what do you think?
(function($){
var methods = {
init: function(val){
// Actions to initialize ALL selected Elements
}
,
returner: function(val){
alert('working with every selected element: '+$(this).width());
// return anything
return 'STRING PRODUCED BY THIS FUNCTION!';
}
}
$.fn.myplug = function(method){
var args = arguments;
var init = 'init-myplug';
return this.each(function(){
var is_init = $(this).data(init);
if (is_init && methods[method]){
return methods[method].apply($(this), Array.prototype.slice.call(args, 1));
} else if (!is_init && (typeof method === 'object' || !method)){
$(this).data(init, true);
return methods.init.apply($(this), Array.prototype.slice.call(args, 0));
}
});
};
})(jQuery);
$('.selects_5_elements').myplug(); // init
$('.selects_5_elements').myplug('returner'); // get the string
Upvotes: 4
Views: 2373
Reputation: 1673
The only thing you need to do is to put it into EACH callback:
if ( args.length === 0 ) {
// Init your plugin
return this;
}
if ( args[0] === "returner" ) {
// Generate your string
return "STRING PRODUCED BY THIS FUNCTION!";
}
Upvotes: 0
Reputation: 23001
The first step would be to gather the results from your method. At the moment you are trying to return the result of the method through the each callback, which isn't going to work (the return value in the each callback is used to break out of the loop).
I would suggest gathering all the results in an array like this:
var results = [];
this.each(function(){
var is_init = $(this).data(init);
if (is_init && methods[method]){
results.push(methods[method].apply($(this), Array.prototype.slice.call(args, 1)));
} else if (!is_init && (typeof method === 'object' || !method)){
$(this).data(init, true);
results.push(methods.init.apply($(this), Array.prototype.slice.call(args, 0)));
}
});
At this point you could simply return the results array. But if you want to allow some methods to be chainable, while others return the results of the method call, then you would need to check the method name to decide what value to return.
if (method == 'returner')
return results;
else
return this;
Also, note that we are returning an array here, not a string. The reason is that your method is going to be called for every element matching the selector. So if you have five matching elements you are going to get an array of 5 strings.
If you really just want a single string back, then you need to decide how to handle all the duplicates. Do you want to join all the strings together? Or only return the first string? Or only the last string? All options are easy enough to do - which you choose will depend on your requirements.
Upvotes: 2