Tuesday, March 24, 2009

Tips & Tricks when working with jQuery and ASP.NET AJAX

For example when calling slideUp(speed, callback) or slideDown(speed, callback). Same thing when calling each(callback) function except that the callback in each(callback) function takes 2 arguments while those in Effects functions take no arguments by default -refer to jQuery documentation for more details-.

What are the issue exactly?

In all callback function in jQuery, "this" keyword will reference the DOM Element. For example in slideUp or slideDown functions if you specified a callback like this:

1. //Collapsed is your callback function
2. $('#elementId').slideDown(Collapsed);

//Collapsed is your callback function
$('#elementId').slideDown(Collapsed);


Your callback function Collapsed should look like this:

1. function Collapsed() {
2. //"this" refers to dom element
3. }

function Collapsed() {
//"this" refers to dom element
}


Now if you used "this" keyword in the callback function context it will reference the DOM Element which you are sliding down or up or making any kind of effects on it.

Why would this be an issue?

This should cause an issue with ASP.NET AJAX library if you are building an AJAX control or extender control and using jQuery with it. Because is you fall in such thing, you might need to access properties, methods or local variable of your client control you made with ASP.NET AJAX. And typically you would do that using "this" keyword. Have a look at the following example:

1. this._componentLocalVaiable = 'some value';
2. $(something).each(,function(i,domElement){
3. //how to access _componentLocalVaiable inside callback function context?
4. });

this._componentLocalVaiable = 'some value';
$(something).each(,function(i,domElement){
//how to access _componentLocalVaiable inside callback function context?
});


If you tried to do something like this._componentLocaVariable inside the callback function context you'll get an error. Because "this" will refer to DOM Element.

What is the solution?

The solution is in ASP.NET AJAX library. It is within the use of the Function.createCallback function. There is good post by Bertrand Le Roy on How to keep some context attached to a JavaScript event handler? which exactly what I am going to do and I recommend that you read his post.

So how createCallback function is going to solve this issue? it is exactly how Bertrand stated his post title, by keeping some context attached. And this context would the a reference to the client control itself.

Let's say you have a private function called "__callback" that you'll use it as the callback function for jQuery each function. Your "__callback" should look like this inside your client control:

1. __callback: function (i,domElement,context){
2. // Code here
3. }

__callback: function (i,domElement,context){
// Code here
}


Did you noticed the 3 arguments? first 2 are the default arguments provided by jQuery. The 3rd one will be passed as a context when using createCallback function as I'm going to show now.

In your code and before calling each function you can create a callback using this line of code:

1. var callback= Function.createCallback(this.__callback, this);

var callback= Function.createCallback(this.__callback, this);


Now here in the code snippet above, you noticed that I'm using "this" keyword. Yes because I am still inside my client control context. Also I passing "this" as a context. This way in my __callback function I have a reference to my client control through context argument.

It is time to call each function now:

1. $(something).each(callback);

$(something).each(callback);


Or you can do this directly:

1. $(something).each(Function.createCallback(this.__callback, this));

$(something).each(Function.createCallback(this.__callback, this));


Conclusion:

I made a demonstration above on each function but this all applicable for all callback functions used in jQuery Effects as well. I faced this issue in while I was building the jQueryCollapsiblePanel control but with Effects functions such slideDown(speed, callback) and slideUp(speed, callback).

I hope this post would be use or help to anyone who intended to build AJAX Enabled controls with jQuery support.