Scope problems with JavaScript setInterval & setTimeout? Use closures!

JavaScript closures is one of those topics which, I always thought, is beyond my head. Though several articles explain the concept, somehow, I was often confused.

I was working on a thick client application, which heavily uses lot of jQuery and JavaScript. I need a client side timer to run periodically, to keep user's session alive and so I was using JavaScript's native "setInterval()" method for my timer. Everything was fine, till I suddenly faced a weird problem.

Suppose, you have created a  global function which is to be fired periodically. In simple JS, it can be written as:

var timer=function (){ 
    console.log('my timer'); 
}; 
var timerId=setInterval('timer();',1000); 

This works perfectly well. Here the function "timer()" is at a window level and has global scope. So no issues so far.

However, to clean up the code, if you follow any of these patterns,  you will have good code, but setInterval will not work! See the below code for more clarity:

var TestObject=function(){ 
    var timerId; 
    this.timer=function(){ 
        console.log('test timer'); 
    }; 
    this.startTimer=function(){ 
        timerId=setInterval(function(){ 
            this.timer(); 
        },1000); 
    }; 
    this.stopTimer=function(){ 
        clearInterval(timerId); 
    }; 
}; 
 
var obj=new TestObject(); 
obj.startTimer(); 
obj.stopTimer(); 

In the above code, TestObject is the class which is holding the entire code, so that all my functions are not exposed to global window object. "timer()" is a public function which will be fired periodically and "startTimer()" is the function which will trigger the timer.

If you run the above code (you can quickly try in firebug console), you will get a JavaScript error - "this.timer is not a function". The reason is, setInterval() function will take the scope to window object and this will check for "timer()" at window level. Since you are wrapping it in "TestObject", "timer()" will not be found. To solve this scope problem, you need to use closures and store the instance of the class. So the "startTimer()" function should be like:

this.startTimer=function(){ 
      var inst=this; 
      console.log('startTimer this: ',this); 
      timerId=setInterval(function(){ 
          console.log('setInterval this: ',this); 
          inst.timer(); 
      },1000); 
}; 

The above code has two console statements. The “this” keyword in the first console statement prints the instance of TestObject, while the “this” keyword in setInterval function prints “window” object. This shows that setInterval function will take the scope to window level and hence it is not able to find “this.timer” in the first snippet.

Notice that we are storing the instance of TestObject class in a local variable "inst". Also notice that setInterval is using an anonymous function, which is forming a closure. In this anonymous funtion, we are able to access timer() function using "inst.timer()". This would solve the scope problem! setInterval function will be called for every 1 second and it will always have access to “inst.timer()”. This is the power of closures.

To explain closures in my words,  when there are nested functions, the child function will have access to local variables of parent function(which is as expected). But after the parent function has executed, the child function, when called explicitly, will still have access to the local variable of parent function. JavaScript garbage collector will not clear the value of the variable.

For a graphical explanation of JavaScript closures in jQuery context, please check BenNadel's blog. Ben explains the concept of closures very clearly in this article.

Happy coding :)

Check for unsaved data on your web forms using jQuery

One of the most important Usability requirements in business applications is, to periodically inform the users when there is any unsaved data on their web pages. This can be seen in email apps like Live mail/Gmail (compose a new mail and try to navigate to Inbox, without saving or sending the mail. An alert will pop out asking to save the mail).

To meet this requirement, one page load, one should loop through all the controls of the page, store the initial values of the controls, bind blur event handlers to all the controls, on blur event compare the final value with the initially stored values. If there is any change in the value, mark the form as dirty (unsaved data), else mark it as clean (saved data).

jQuery Dirty Form plug-in:

I started writing my own code, but found the beautiful dirty form plug-in. Thanks to the author Wilson for the plug-in, which does exactly the same as my pseudo-code. To check for a dirty form, all you need to do is:

$(document).ready(function(){
   $("#YourFormId")
     .dirty_form()
     .dirty(function(event, data){
       //The dirty event fires when you blur from a control after changing its value.
     })
 });

The plug-in is not well documented, hence you should spend time walking through the code. The plug-in will set a flag to the form’s data, to indicate if it is dirty or not, like this:

form.data("dirty", true) 

The dirty() event in snippet 1 will set the dirty flag to true. So at a later stage if you need to check the form’s status, you should use the form’s data. To a good extent I could leverage the the plug-in, but to meet my project specifications, I had to tweak it a lot.

Bug in Dirty Form plug-in and fix for the bug:

The plug-in has a function called “input_checker”, which will check for form status on each control’s blur. As said earlier, it will compare the initially stored values with final ones, which is fine. However, if you switch between forms, the data of one form will be compared with data of latest form, which spoils the show. I’m not sure why others haven’t raised the bug, but I’m very sure of it. Hence publishing the below fix:

In the “input_checker” function, replace the below code

input_checker : function(event){
    var npt... ... ...
    inputs = event.data.inputs, settings = event.data.settings

with this one:

input_checker : function(event){
    var npt ... ... ...
    inputs = $(':input:not(:hidden,:submit,:password,:button)', form), settings = event.data.settings

What is happening is, the plug-in is caching all the inputs to be checked in data parameter of the form. When we navigate to a new form, the controls of old form(from cache) are being checked, instead of the controls from new form. Hence I am querying the controls of new form again and using it for comparison. This would solve the problem :)

Here are some of the functionalities which I could leverage using the plug-in:

(1) On page load you can disable save buttons and enable them only in the dirty() event.

(2) You can check for form dirty flag and decide to extend user’s session accordingly.

(3) You can give a warning when user navigates to another page without saving data (similar to Gmail/Live mail).

Thanks to Wilson once again for the plug-in. Hope the fix would help some of the folks who are facing similar issues. 

Happy coding :)

jQuery event delegation - Adding/removing markup dynamically

First of all, my Happy New Year wishes to all netizens! As you journey through 2010, leave a trail of hardwork, innovation, passion and excellence...

Coming to the topic, in web apps, most of the times, we would require adding and removing controls to a web page dynamically. E.g.,adding "Browse" buttons for email attachments(live mail, gmail etc). In a traditional ASP.NET app, we used to build a string containing markup and append it to some control. However, this requires postback. Here is the end result which we would want to achieve:

With the help of jQuery, we can achieve this functionality with ease. Let us see the various ways of implementing this functionality.

1. Using jQuery “clone(true)” function:

Many of us know about jQuery clone() function, which will clone any jQuery selector. But the hidden feature is, it accepts a boolean parameter. When the param is set to true, it will clone DOM elements along with their event handlers.

Though this method can help us achieve the end result, the disadvantage is, it will fail to initialize complex controls like date pickers, auto suggest textboxes etc.

2. Using jQuery “live” event:

jQuery live looks like a perfect choice for this requirement. Live events are added for current as well as future elements in the DOM and hence events for “+”, “-“ buttons can be written only once using Live.

Though this works as expected in simple screens, even this is not a perfect approach! If suppose you are loading pages via AJAX, the events would be bound multiple times. So clicking on “+” will add more than 1 row, as multiple click events are bound. This is because, Live adds events to the document and not to the element. Check this article to see how live works.

3. Using jQuery Event Delegation:

Yup! This will solve the problems caused by above methods. I don’t want to explain about event delegation as there are very good articles already available. Check these:

The concept is very simple. Suppose you have a html table with 100 cells and you need to fire an event when any cell is clicked, instead of writing the below code:

$('#myTable TD').click(function(){
    $(this).css('background', 'blue');
});

you can write code like this:

$('#myTable').click(function(e) {
    var clickedElement = $(e.target);
    clickedElement.css('background', 'blue');
});

So instead of binding 100 events as in case 1, you can achieve the same output by binding only a single event, as in case 2.

This will solve the problem of Live, as the events are not added at document level, but are added to parent container. This will also solve the problem of Clone as date pickers will be initialized properly.

DEMO: Here is a demo for the above functionality using LIVE (Use it only when you are not loading pages via AJAX). I shall very soon come up with a demo using event delegation. This is a real time problem which I faced in a large scale project. So wanted to share immediately, so that others might not fall in the traps in which I fell!

Happy Coding :)

Handling AJAX exceptions of ASP.NET using jQuery

Exception handling is an important feature in any business application. In simple words, it is all about catching ugly errors thrown by server and displaying them in a user friendly manner to the end user. (Of course, logging exceptions/notifications etc may also be a part of exception handling. )

ASP.NET provides API for handling exceptions and displaying them in custom error pages. Custom error pages can also be defined for different HTTP error status codes, which provides good experience to end users in case of exceptions.

However, if you are using AJAX in your ASP.NET application(I’m using jQuery library for AJAX), you would not like to redirect users to a custom error page, as that kills the primary motto of AJAX. You would instead like to display error messages in the same page, as in facebook or twitter. So here is how this can be done using jQuery:

jQuery’s $.ajax method has a special function, $.ajaxSetup, where global settings can be made for handling AJAX requests. If you use this global function, you need not write error callbacks for each of your AJAX requests. All erroneous AJAX requests will be handled by the global error callback in $.ajaxSetup function. We can take advantage of this and write our exception handling wrapper.

$.ajaxSetup({
    error: function(XHR, errStatus, errorThrown) {
 
        if (XHR.status == 0) {
            alert('You are offline!\n Please check your network.');
        } else if (XHR.status == 404) {
            alert('Requested URL not found.');
        } else if (XHR.status == 500) {
            var errorMessage = 'Internal server error';
            try {//Error handling for POST calls
                var err = JSON.parse(XHR.responseText);
                errorMessage = err.Message;
            }
            catch (ex) {//Error handling for GET calls
                $('#divMaster').append('<div id="divErrorResponse" class="DisplayNone">' + XHR.responseText + '</div>');
                errorMessage = 'Page load error: ';
                errorMessage += $('#divErrorResponse').find('h2 i').html();
            }
            alert(errorMessage);
        } else if (errStatus == 'parsererror') {
            alert('Error.\nParsing JSON Request failed.');
        } else if (errStatus == 'timeout') {
            alert('Request timed out..Please try later');
        } else {
            alert('Unknown Error.\n' + XHR.responseText);
        }
    }
});

In the above code, we are checking for status codes(which are self explanatory) and handling error conditions based on these codes. Most of the times, the status code will be “500”, which says “Internal Server Error”. i.e., error in your server side code. Please refer this article from Encosia.com, which explains the core of what I am writing now.

Now, this “500 – Internal Server Error” may arise in both GET as well as POST requests. In POST request, if your web method throws error, it returns a JSON object, which you can parse as explained in the above link. But this does not work in case of GET requests.

Assume that you are loading a remote page into a master page using jQuery AJAX. If your “Page_Load” event throws exception, your response would be in HTML format (unlike the case of POST request, where the response is JSON object), which you cannot parse using JSON.parse or eval(). To differentiate between GET & POST responses, I’m simply using JSON.parse() in try() method. If it throws exception, it is surely due to a GET response, which is html. For better user experience, you may use jGrowl plugin for displaying error messages.

Conclusion: For exceptions in GET requests, you can query the resultant html using jQuery’s DOM selectors and display user friendly messages. For exceptions in POST responses, you can simply parse the resultant JSON object and display user friendly messages. If you feel there could be a better way of handling exceptions in GET requests, let me know.

Hope this article saves the time of folks who are facing similar problems. Happy coding :)

Client side localization in ASP.NET using jQuery

Localization is a very important feature required in medium-large scale business applications. As always, ASP.NET makes developers life easy by providing inbuilt localization mechanism. Using resource files, all the elements in a web page can be localized.

However, if you are building a rich client side app using JavaScript/jQuery, you may need to fetch error messages and other strings from locale specific external file, without post back. In such cases, jQuery localization plugins come to rescue. Below are some of the best jQuery plugins, which help in localization:

  1. http://keith-wood.name/localisation.html
  2. http://codingwithcoffee.com/?p=272
  3. http://sundaymorning.jaysalvat.com/ 

The third one is cool with integrated Google translation API,  The second plugin is used by jqGrid & other plugins for localization. However, I really loved the first one - Keith wood's plugin, which gives a basic but powerful localisation features. All it does is, make synchronous call to the server and load locale specific JS file, which will override the variables of your base file. When you use custom events to change localized messages, the first one is the best, owing to its simplistic nature.

The question now is, how to get the UI culture of user's browser on page load.

Though the plugin is expected to do this, somehow, this is a missing feature. But you need not worry, as ASP.NET does this easily for you.In the "Session_Start" event of global.asax, just use this code:

Response.Cookies("UICultureCookie").Value = Request.UserLanguages(0)

This stores the first preferred UI culture of user's browser in a cookie. Using the information in this cookie is pretty simple using jQuery's cookie plugin. Just say:

var clientCulture = $.cookie("UICultureCookie");
$.localise('JavaScript/Constants/constants', { language: clientCulture }); 

That's it!  Now even your client side messages in ASP.NET can be localized, without postback, using the power of jQuery.

P.S:  I didn't write much about how to use these plugins, as their home pages have clear documentation & demos, which are self explanatory.

Love JavaScript design patterns, love your jQuery code even more!

The goal of this article is to educate budding jQuery developers (who do not have much exposure to JavaScript), to write clean, readable, maintainable code. This is in fact, a pointer to articles written by several JavaScript gurus.

For a jQuery developer, who does not have good expertise of JavaScript object oriented programming concepts, the entire code of a JavaScript file would reside in the "$(document).ready()” function. This includes various events, ajax calls, their call backs, UI effects etc.

In the case of a large scale business application (having hundreds of JavaScript files, each file having few thousands of lines), this would mean a lot of effort during reviews, white box testing and especially maintenance. Therefore, apart from learning the library, knowledge of good practices of core JavaScript language is a must.

Here is a collection of some of the best links, which would change the way you code. Read them in this sequence :)

1. JavaScript Best Practices by Christian Heilmannhttp://dev.opera.com/articles/view/javascript-best-practices/

2. Show love to the object literal - http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/

3. Closures and lexical scoping in JavaScript - http://mark-story.com/posts/view/picking-up-javascript-closures-and-lexical-scoping

4. Private Members in JavaScript by Douglas Crockford - http://www.crockford.com/javascript/private.html

5. JavaScript programming patterns - http://www.klauskomenda.com/code/javascript-programming-patterns 

6. Five things to do to a script before handing it over to the next developer - http://www.wait-till-i.com/2008/02/07/five-things-to-do-to-a-script-before-handing-it-over-to-the-next-developer/

Out of all the JavaScript design patterns in link #5, these are quite popular:

 a. Singleton pattern [Thanks to HB Stone for explaining the concept in simpler terms]

 b. Module pattern [Thanks to Christian Heilmann for the contribution]

 c. Revealing module pattern [An updation to module pattern by Christian Heilmann]

I have tried these and like many others, I fell in love with the Revealing module pattern. The core of these patterns is the concept of closures. So make sure you are good at the basics!

Before trying out patterns, my jQuery code was like this:

$(document).ready(function() {
   //page load ajax call 
    $.ajax({
        type: "POST",
        url: "CTypesHandler.ashx",
        data:"{}",
        success: callBackFunction,
        error: function(){}
    });
 
    //ajax success callback function
    callBackFunction(response)
    {
        //process ajax response here...
    }
    
    //form validation code
    $('#FormId').validate(){
        //code for validation
    }
    
    //click events
    $('#submitButton').click(function(){
      //code for submit click event
    });
    
    $('#saveButton').click(function(){
      //code for save click event
    });
});

After trying out Revealing Module pattern, my jQuery code is very clean like this:

var mySamplePage=function(){
    var counter=0;
    
    var callBackFunction = function(response)
    {
        //process ajax response here...
    };
    
    var pageLoadAjaxCalls=function(){
        $.ajax({
            type: "POST",
            url: "CTypesHandler.ashx",
            data:"{}",
            success: callBackFunction,
            error: function(){}
        });
    };
    
    var bindEvents=function(){
        $('#submitButton').click(function(){
          //code for submit click event
            counter++;
        });
        
        $('#saveButton').click(function(){
          //code for save click event
        });
    };
    
    var validate=function(){
      $('#FormId').validate(){
          //code for validation
      };
    };
    
    var pageLoadOperations=function(){
        validate();
        pageLoadAjaxCalls();
        bindEvents();
    };
    
    return{
        init:pageLoadOperations
    };   
}
 
$(document).ready(function(){
    vare page= new mySamplePage();
    page.init();
});

To explain the differences in short, the first snippet has all code in document.ready function. This means, all variables, functions used are global. There is no modularization in the code. So if new events, UI logic are to be added, they add up to the mess.

In the case of patterns snippet, the code is clearly modularized. There are no global variables/functions. All members, functions are private. Only certain methods are exposed(by adding pointer in return statement). If new code has to be added in future, it can be added to the respective functions (like pageLoadAjaxCalls, bindEvents etc). Our document.ready is now very clean, and has control on what to be done, with ease.

Using good jQuery selectors gives optimized code; Using JavaScript design patterns gives clean and maintainable code. Happy coding :)

jQuery UI AJAX Tabs – few hiccups & resolutions

Developers who have tried jQuery UI Tabs plugin might have tried AJAX mode, which is really useful in meeting several requirements. The documentation clearly explains how to start using AJAX tabs.  However, there would be few hiccups if the plugin is not clearly understood. Below are some of them which I have faced recently:

Problem 1: In AJAX mode, sometimes, tabs do not load on a single click. You need to select a tab twice (double click) to open a tab.

Reason: Unfortunately, this is due to a bug in the plugin and happens when your AJAX calls fail.  Error handling is not done properly in jQuery tabs plugin as of the current version(1.7.2). More about this bug here. It can be resolved by applying the patch as described in the ticket. Hopefully, it would be fixed in the next release.

Problem 2: The “spinner“ option does not work by default (Spinner lets you provide a default “loading…” message in the tab, during tab load).

Resolution: To show spinner, the content of anchor tags inside “<li>” must be enclosed in “<span>” tags. More info here…

Problem 3: Displaying custom “loading” message in the tab body (and NOT in the tab).

Resolution: Overwrite the default spinner and make use of “select”, “show” functions. More Info here…
(Note: When tabs are cached, “load” will not get triggered for the second time. So use “show” instead of “load” while caching).

Problem 4: Remove “flickering” of tabs on page load.

Resolution: As you might have expected, simply hide the tabs container using CSS (display:none) and show it using jQuery after tabs are built as below:

$('#TabsDiv').tabs({.....}).css('display','block');

Problem 5: Tab panel/body is not removed from the DOM when a tab is closed.

Resolution: This is indeed a tricky problem. This happens when tabs are disabled! Wondering what is the relation? It’s simple. When a tab is disabled, the “<li>” element, which makes the tab header, will be displayed in a dull style. But the corresponding “div”, which makes the tab panel/body is not rendered.

So, there would be a difference in indexing between tab header & body and thus the tab body is not deleted. Hence, do not disable tabs when you want to remove them based on index! (You may debug the first two lines of “remove:” function in the plugin to test this).

Problem 6: Prevent “auto selection” of adjacent tab, when a tab is closed.

Resolution: The Tabs plugin mimics “Firefox” tabs with respect to auto selection of a tab, when another tab is closed. However, sometimes, you might need to select a farther tab on closing of a particular tab. This cannot be achieved by overriding the “remove” callback. So simply comment the below lines in “remove” function and write your code to select the desired tab in your close button click event.

// If selected tab was removed focus tab to the right or 
        // in case the last tab was removed the tab to the left. 
        if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) { 
            this.select(index + (index + 1 < this.anchors.length ? 1 : -1)); 
        }

Note: I’m using jQuery tabs inside UI.Layout plugin in my project. At first, I thought that the layout plugin is messing up my code and causing these issues. After straining for 3 days, I could figure out the above solutions. So folks using the UI.Layout plugin need not worry about Tabs plugin integration. Their combination works perfectly.

Hope this article saves the time of many enthusiasts who might face similar problems. Happy coding :)

Using jQuery cluetip plugin for validation callouts.

Displaying validation messages using callouts is a good way of educating the user on what has to be filled on the form. ASP.NET AJAX's Validator callout does a good job in this aspect. But how about implementing the same using jQuery?

I was googling for this and quickly came across jQuery validator callout plugin. This is an excellent plugin which suits many forms. However, I could not use it as it displays callout either on the top or bottom of the textboxes. I need callouts to be displayed to the right/left side of textboxes. I tried to customize it, but without much output. So tried for other options.

It struck me that I can use jTip for this requirement. However, jTip expects every call to be an AJAX call. So finally came to clueTip and yeah, I'm on the right track. The output would be something like this:


One good point which makes me feel this approach is better than ASP.NET AJAX toolkit callout is, unlike the toolkit callout, I need not write HTML for each and every popup. Just place the div at one place in your mark up and hide it. Reuse that piece for every call out.

How to use clueTip as Validator callout?

First, please check how clue Tip works. If you are aware of how to use clueTip, the below code would be a cake walk.

1. Place a div in your HTML like this: <div id="ValidationMessageDiv"></div>

2. Create 2 JavaScript functions "showCallOut(element,errorMessage)" and "removeCallOut()".

3. In the validation code for your "Submit" button, write this:

$("#SubmitButtonId").click(function() {
   if (ContactNumberText.val() === '') {
      showCallOut('ContactNumberTextId', "Please enter contact number"); 
    }
}); 

That's it! You can now use the showCallOut(,) function in every button click.

Here are the definitions of the fuctions used:

function showCallOut(element,errorMessage) {
    element = '#' + element;
    $(element).addClass('jt ui-state-error').attr('message', errorMessage);
 
    var firstErrorElement = $('.ui-state-error:first');
    var firstErrorElementTop = firstErrorElement.offset().top;
 
    $(element).attr('title', 'Required field')
        .attr('rel', 'div[id="ValidationMessageDiv"]')
        .cluetip({
            local: true, cursor: 'pointer',
            cluetipClass: 'jtip', width: '150', //sticky:'true',
            arrows: true, dropShadow: false, hoverIntent: false
        });
    firstErrorElement.focus();
}
 
function removeCallOut() {
    $('.ui-state-error').unbind('focus.cluetip');
    $('.ui-state-error').removeClass('jt ui-state-error').removeAttr('message')
        .removeAttr('rel').removeAttr('title');
} 

I just made the showCallOut function a bit intelligent, so that if a form has 10 mandatory fields, it will add "ui.state.error" class to every control (Remember? This class is jQuery ThemeRoller's class for highlighting error controls). By default the first control will be focussed and callout comes out. If you switch the focus to another control, the callout disappears for first control and reappears for second control.

If you want to remove the callout after validating the field, just use the removeCallOut() function.

This is just an idea for those who are struggling with similar requirement. I will try to come up with a demo so that it would be more clear.

Configuring jqGrid 3.5 to work with ASP.NET web forms and JSON

If you are an ASP.NET web developer using jQuery for AJAX, you would have probably got used to passing parameters through DTO (Data Transfer Objects) as suggested by Dave in Encosia.com. This is a clean and simple approach for passing parameters from client to server.

Unfortunately, many jQuery plugins are not coded this way and need to be tweaked. Same is the case with jqGrid, which is an excellent jQuery grid plugin. So below are the simple tweaks to be made for jqGrid to support DTO's.

At a basic level, these tweaks should be  done in the "grid.base.js" file. If you are using plugins for inline edit or any other feature which makes AJAX calls, the same changes have to be made there also.

There are things which need to be changed in all AJAX calls made by the plugin:

1. Building a Data Transfer Object(DTO).

2. Setting the content-type to "application/json".

3. Convert the input object into  JSON string.

4. Filtering .NET's "d" parameter in the AJAX success function.

1. Building a DTO: In "grid.base.js", search for the code "populate = function() { ", which is the definition of populate function (This is in line 577). In this function, add the code in bold, above the switch statement (which is in line 588).

var jsObj = { 'obj': ts.p.postData }; //Building a DTO
switch (dt) {
                    case "json":
                    case "xml":
                    case "script":

2. Setting the content-type to "application/json":

  In line 593, add the JSON content type as a parameter to $.ajax function.

3. Convert the input object into  JSON string:

 In the same lin(593), replace the data parameter with JSON stringified DTO.

The code change for (2) and (3) will now be:

  Old Code:  $.ajax({url:ts.p.url,type:ts.p.mtype,dataType: dt ,data: ts.p.postData, 

  Tweaked code: $.ajax({ url: ts.p.url, type: ts.p.mtype, dataType: dt, contentType: 'application/json; charset=utf-8', data: JSON.stringify(jsObj),

 4. Filtering .NET's "d" parameter in the AJAX success function:

Finally, filter .NET's "d" parameter in the line 596 like below:

  Old code:   if(dt === "json" || dt === "script") addJSONData($.jgrid.parse(req.responseText),ts.grid.bDiv,rcnt);

  Tweaked code:  if (dt === "json" || dt === "script") addJSONData($.jgrid.parse(req.responseText).d, ts.grid.bDiv, rcnt);

That's it! The grid should now be able to handle JSON objects as input parameters and should bind JSON data successfully. Note that I have done these tweaks in jqGrid 3.5. The same concept applies to lower versions of jqGrid too. However, the line number and variables used in AJAX calls differ.

Hope this article would save the time of many enthusiasts, who want to use jqGrid in their ASP.NET projects. I shall come up with a detailed post on other common problems shortly.

Using .NET’s Register Script methods with jQuery’s $(document).ready()

In ASP.NET web apps, most of the times we would need to call JavaScript functions in page_load event of code behind, for various valid reasons. In such scenarios, we simply use .NET’s Register Script methods for emitting JavaScript code, which is absolutely fine.

If you are using jQuery, you would write the logical flow of events to be executed in $(document).ready() function. However, if you are using Register script methods with jQuery, the output will not be as expected. I have faced this problem yesterday and want to share the reason and simple solution.

.NET framework provides two methods for emitting JavaScript to the client. They are:

  1. RegisterClientScriptBlock (Client-side script is emitted just after the <form runat=”server”> tag)
  2. RegisterStartupScript (Client-side script is emitted just before the </form> tag)

Note: These methods are now moved to ClientScriptManager class from Page class.

The below screenshot explains the difference clearly:

 

Okay. Now that the difference between the two is clear, let us go forward. Consider the below simple JS code:

function fnTestScript(msg) {
    console.log(msg);
}
 
$(document).ready(function() {
    fnTestScript('This is from document.ready');
});

We am defining a method fnTestScript(parameter) and calling it in jQuery’s ready() function. Now, in page_load event of server, let us call this method using Register script methods.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
       'Using "RegisterClientScriptBlock" method to emit JS code.
       Dim strScript As New StringBuilder
       strScript.Append("<script language='javascript'>")
       strScript.Append("fnTestScript('This is from RegisterClientScriptBlock');")
       strScript.Append("</script>")
       ClientScript.RegisterClientScriptBlock(Me.GetType(), "TestScript", strScript.ToString())
 
       'Using "RegisterStartupScript" method to emit JS code.
       Dim strScript2 As New StringBuilder
       strScript2.Append("<script language='javascript'>")
       strScript2.Append("fnTestScript('This is from RegisterStartupScript');")
       strScript2.Append("</script>")
       ClientScript.RegisterStartupScript(Me.GetType(), "TestScript", strScript2.ToString())
   End Sub

Can you guess what the output will be? Here it is:

RegisterScriptsOrder

The reason is simple. .NET is injecting the script inline, into the DOM. So its functions are called before $(document).ready(), which fires after DOM is loaded. This means, your logical sequence of JavaScript calls has gone for a toss!

The solution is even more simple. Just add $(document).ready() in your function definition:

function fnTestScript(msg) {
    $(document).ready(function() {
        console.log(msg);
    });
}

Now your sequence of JavaScript calls will be like this:

RegisterScriptsOrder2

Q: Can you call $(document).ready() multiple times?
A: Yes!
This is another difference between this method and JavaScript’s window.onload, which is rarely mentioned in articles. The order of execution depends only on the order in the code.

Hope this article saves the time of others who face similar problem!