views:

83

answers:

4

I would like the below function to be more flexible and accept multiple callbacks to other functions if they are defined in the arguments.

$(function() {
                function icisDashBox(colorElem, thisWidth, thisHeight, completeCallBack) {

                    $(colorElem).colorbox({
                        transition: 'none',
                        innerWidth: thisWidth,
                        innerHeight: thisHeight,
                        opacity: '0.5',
                        onOpen:function(){ 

                            },
                        onLoad:function(){ 

                            },
                        onComplete:function(){ 
                            $('#cboxLoadedContent').wrap('<div id="icis_dialog_msg" />'); 

                            completeCallBack();

                            },
                        onCleanup:function(){ 

                            },      
                        onClosed: function() {
                           $('#cboxLoadedContent').unwrap(); 
                        }
                    });
                }

                icisDashBox('.example9', '500', '500', completeFunction);

                function completeFunction() {

                    var fooClass = $("#colorbox").addClass("FOO");

                    var barClass = $("#colorbox").addClass("BAR");

                    var ajaxCnt = $.ajax({
                                   type: "GET",
                                   url: "http://www.payso.me.uk",
                                   dataType: "html",
                                   success: function(data){
                                     $("#colorbox").addClass("AJAX SUCCESS");
                                   }
                                 });

                    return {

                        x : fooClass,
                        y : barClass,
                        z : ajaxCnt

                    };
                }
            });

So in an ideal world my function would look like this without explicitly declaring any arguments:

function icisDashBox() { function code here }

Is this possible? Also if the arguments are not defined how do i handle that?

For example if one call to the function has several callbacks defined and another only has one is there a way of handling the lack of presence of callbacks.

Cheers,

:)

+2  A: 

Just loop over the arguments object: https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/Arguments

David Dorward
+2  A: 

Use arguments variable.

function TestMe()
{
   var args = arguments;

   for (var a in args)
   {
     alert(args[a]);
   }
}

Now you can pass any number of arguments to TestMe function:

TestMe(1);
TestMe(1,2,3);
TestMe(1,2,3,4,5,6);
TestMe.apply(this, [1,2,3,4,5]); 

etc.

rochal
+7  A: 

You can use the keyword arguments which is an array of the passed arguments, like this:

function myFunc() {
   if(arguments.length > 0)     //be sure to check if there are any...
     var arg1 = arguments[0];
}

However, a much better approach is to accept an object, e.g.:

function myFunc(settings) {
   settings = settings || {};   //in case it was called as just: myfunc()
   var something = settings.something || "default value";
}

You'd call it like this:

myFunc({ something: "value", somethingElse: "otherValue" });

This approach allows you to accept any number of arguments as well, but also have any optional, without a bunch of myFunc(null, null, null, "value") type calls to provide only the parameter you want, plus they're named making this much more maintainable IMO. Here's an edited version of the plugin to demonstrate this.

Nick Craver
Thanks Nick i will look into this approach i think.I assume that 'settings' becomes global due to the omission of 'var' and would need to be namespaced?
RyanP13
@RyanP13 - Nope not global, since it's a parameter name it's local to the function, you're already covered there :)
Nick Craver
+1 For passing an object, also keep in mind that whenever you encounter a situation where you can't remember the arguments(like for example your function takes 5 ints) refactor it to take an object.
Ivo Wetzel
Thanks to all for great answers. This has been a massive help like you would not believe.Have updated the code here to view:http://jsfiddle.net/7NZ7M/
RyanP13
@NickWould i always have to pass functions to the 'callback' properties of the settings object?I tried this and it seemed to work:onLoadCall: $('body').prepend('<span class="prepend"/>'),But i am not sure it should if you know what i mean?
RyanP13
@RyanP13 - Try something like this, more compact and easier to maintain :) http://jsfiddle.net/nick_craver/7NZ7M/1/
Nick Craver
@RyanP13 - Yes you'd need anonymous functions, otherwise it runs the code immediately, so you'd need `onLoadCall: function() { $('body').prepend('<span class="prepend"/>'); }` as the option. If it's a named function you'd just go `option: functioName`, no parenthesis.
Nick Craver
@ NickSorry what is going on here: if(typeof options.onCompleteCall == "function") options.onCompleteCall.call(this);Doesn;t look like a normal if statement and if we are alwasy passing functions, named or anonymous why is it needed?
RyanP13
@RyanP13 - It's checking that what was passed was a function, so if you did `onCompleteCall: "bob"`, it wouldn't blow up trying to do `"bob".call(this)`, since `string` doesn't have a `.call()` function...just a safety check :)
Nick Craver
+2  A: 

Yes this is possible, here's an example :

function myfunct()
{

  var arguments = myfunct.arguments;

  for (var i = 0; i < arguments.length; i++)
        {

                alert("Argument " + i + " value = " + arguments[i]);

            }

}

You can call this fonction by any number of arguments :

myfunct("foo");

myfunct("foo","bar");
youssef azari