MasterT
MasterT

Reputation: 623

Jquery passing a function to a function

OK, i need some help,

i have a function inside a jquery plugin

var LoadPage = function (page, location, func){     
        $.ajax({
            url: page,
            success: function(data){        
                $(location).html(data); //Insert data into location
                func
                return true         
            },
        });
    }

i want to use it like this

 Loadpage(
     "api/page.php", 
     "#div_id", 
      $("#calander td.clickable").click(function() {
         var day = $(this).attr("calendar-day");
         console.log("clicked TD" + day);
         LoadPage('/api/view_event.php?d='+day, settings.eventContainer);
  })
 );

or

 Loadpage(
     "api/page.php", 
     "#div_id", 
      function() {
         var day = $(this).attr("calendar-day");
         console.log("clicked TD" + day);
         LoadPage('/api/php/calander/view_event.php?d='+day+'&m='+SelectedMonth+'&y='+SelectedYear, settings.eventContainer);
  }
 );

and then have it run that in the success: where var func is in it but unsure how to get this to work. please help internet.

Upvotes: 0

Views: 78

Answers (2)

jfriend00
jfriend00

Reputation: 707218

There are three separate issues in your code:

1) If you want to execute the callback func in your success handler, then you need to add parens () after it as in func() as that is javascript's method of signifying that you want to execute a function.

var LoadPage = function (page, location, func){     
    $.ajax({
        url: page,
        success: function(data){        
            $(location).html(data); //Insert data into location
            // add parens here after func
            func();
            return true         
        },
    });
}

If you want the func argument to be optional, you can test for it before executing it like this:

var LoadPage = function (page, location, func){     
    $.ajax({
        url: page,
        success: function(data){        
            $(location).html(data); //Insert data into location
            // add parens here after func to actually execute it
            if (func) func();
            return true         
        },
    });
}

2) Then, you need to change how you call LoadPage() to pass it an actual function reference like this:

Loadpage(
     "api/page.php", 
     "#div_id", 
      function() {
         $("#calander td.clickable").click(function() {
             var day = $(this).attr("calendar-day");
             console.log("clicked TD" + day);
             LoadPage('/api/view_event.php?d='+day, settings.eventContainer);
         })
      })
 );

What you were passing it was the result of executing the .click function which is a jQuery object, not a function. Instead, you can wrap that in an anonymous function so you're passing a reference to that function. This is the opposite of the func(). You don't want parens after what you pass because you want to pass a reference to a function, not the result of executing the function now.

So, to summarize these two issues:

The statement:

func

is just a reference to a function. It doesn't actually execute the function. It is useful when you want to pass a reference to a function which will then call it LATER.

The statement:

func()

executes the function immediately. If you pass func() as an argument, then it will execute immediately (parens always mean to execute it now) and then pass the return value of that function (which is not what you want here).


3) You may also want to understand that the return true statement in your success handler does NOTHING. Because the ajax function is asychronous, your LoadPage() function just starts the ajax function and then returns immediately. Sometime later, the internals of the ajax engine calls your success handler. That return statement returns back into the interior of that ajax engine. It does NOT return from your LoadPage() function since that has already long since completed and returned nothing.

4) Possible fourth issue. Every time you call LoadPage(), you are going to add a new click handler to whatever objects this selector matches: "#calander td.clickable". If some of those objects existed previously, you will end up with multiple click handlers. In that case, you would either want to use delegated event handling so you could just install the click handler once ahead of time or you would need to remove the exist click handlers before installing the new ones or you would need to isolate only the newly added objects and only call it on them. If all "#calander td.clickable" are replaced by the previous code, then this would not be a problem.

Upvotes: 2

Tony
Tony

Reputation: 7445

Try this:

var LoadPage = function (page, location, func){     
    $.ajax({
        url: page,
        success: function(data){        
            $(location).html(data); //Insert data into location
            func && func(); // this will execute func if it is passed as parameter
            return true;        
        }
    });
}

And use it in the second way.

Upvotes: 0

Related Questions