Update Multiple Page Elements Using The XMLHTTPRequest Object and JavaScript

19 Jan

In the development of Ajax application many times we will encounter following issues.

  • The requiremnt to update multiple text boxes simultaneously.
  • Fill more that one dropdown list.
  • Update a combination of text boxes, dropdown lists and div tags.
  • Call different web pages and different webservices at the same time.

Imagine the case of a financial data site (such as a stock market info site) with various regions of the page used for displaying data any taking user inputs. We may want to populate fill numerous div tags, textboxes and dropdown lists with real time data. If we loop the several requests and we will also have to check for timeout, if timeout occurs and no data is returned, then we will have to fire the same request again. It may end up that we have made 10 requests and 4-5 requests simply timeout because of network problems. If we dont loop then we will either get whole data or nothing (in which case there is only one more request to be made).

In this article we will discuss the XMLHTTPRequest object and JavaScript and develop a JavaScript class which can asychronously update multiple HTML elements. Also this class can be extended as per the requirements. I have used ASP.NET as the platform in this example but it does as the solution is just Javascript it can be applied to any web development platform.

Regarding classes in JavaScript, technically there is no ‘class’ in JavaScript but we can use a function as a class.

Consider the following code :

function testClass()
{
this.Msg = “Hello”;
this.showMsg = function()
{
alert(this.Msg);
}
}

var obj = new testClass();
obj.Msg = “HI”;
obj.showMsg();

In above script if we remove obj.Msg = “HI”; we will get an alert with text Hello.

We will now develop our JavaScript class step-by-step:

  1. Include JS file and add the following code:

function AjaxClass()
{
this.Method = “GET”;//OR “POST”
this.Async = true; //OR false (asynchronous or synchronous call)
this.request = null;
this.init = function()
{
if (window.XMLHttpRequest) // if Mozilla, Safari etc
this.request = new XMLHttpRequest();
else if (window.ActiveXObject)
{ // if IE
try
{
this.request = new    ActiveXObject(“Msxml2.XMLHTTP”);
}
catch (e)
{
try
{
this.request = new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch (e){}
}
}

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
//we will develope this.handleResponse function in step 3
this.request.open(this.Method, this.url , this.Async);
this.request.send(null);
}
}
}

Here we have created an XMLHTTPRequest object which is simply used to send a call to the server. The default method is GET (this.Method = “GET”) and calling type is Ascynchronous (this.Async = true)

  1. In this step we will develop simple logic which will allow us to dynamically call Ajax function created in Step 1.

For this one JSON (http://www.json.org/) object as follows.

this.JSONArray = {  “Method” : “POST”, //Method type
“Async”  : true, //Call type
“CallPage” : “CallPage.aspx”, //page or webservice
“Querystring” : “”, //Query string
“dependentType” : null,//[0,1,2,3] for isEdit
“isEdit”: [
{
“textBoxId” : null, //0 then this element
“dropDownId” : null, //1 then this element
“default” : null, //2 then this element
“misc”:null //3 then this element
}
]

};

In above script we can set the default values for all elements. We will use these values to set response from the server to textboxes,drop down lists,Div tags, td tags etc. Using “CallPage” : “CallPage.aspx” we can define default server page and while calling Ajax function we can change this value to web method or to any other web page.
As we will proceed in this article we will examine how to change all the above values and how can we use it to update multiple elements.Also we will see that how to extend the class.

  1. Recall from Step 1 : this.request.onreadystatechange = this.handleResponse;

In this step we will develop this.handleResponse function and in this function we will use the JSON object defined in Step 2. Whenever this.handleResponse function gets called script loses the focus of  this. To keep track of this object we will asign it to some variable. i.e var self = this; // To lose of focus of the element

In this function we will be able to receive data from server. Once we receive the data we can manipulate it. This function will handle the responses from web services as well as from web pages. The web service always returns a response in the form of XML whereas the response from the webpage can be any format defined by web developer.

The function will be as follows:

var self = this; // To handle lose of focus
this.handleResponse = function()
{
if(self.request.readyState == 4 && self.request.status == 200)
{
if (window.ActiveXObject) // for IE
{
var doc=new ActiveXObject(“Microsoft.XMLDOM”);
doc.async=”false”;
doc.loadXML(self.request.responseText);
}
// code for Mozilla, Firefox, Opera, etc.
else
{
var parser=new DOMParser();
var doc=parser.parseFromString(self.request.responseText,”text/xml”);
}
try
{
var data  = “”;
if(doc.documentElement) //Response from webservice
data = doc.documentElement.childNodes[0].nodeValue;
else data = self.request.responseText; //from web page
//data contains response text from the server

//At this point we have response from serve
//so here we will write our function to    //manipulate the data. We will develop it in
//4th step.
}
catch(e) {}
}

In the the 1st step we had:

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
this.request.open(this.Method, this.url , this.Async);
this.request.send(null);
}

We will now modify this so that we can directly use the JSON array which we defined in 2nd step:

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
this.request.open(this.JSONArray.Method, this.url , this.JSONArray.Async);
this.request.send(null);
}

While developing Ajax applications we ned to be aware of the following issues regarding domains:

  • URL for XMLHTTPRequest object should belong to same domain.
  • Firefox and other browser doesn’t allow cross domain communication.
  • IE will show warning for cross domain communication.

Thus our this.url = “http://myDomain/mysite/” + this.JSONArray.CallPage + this.JSONArray.Querystring;

e.g. “http://localhost/Demo/CallPage.aspx?”+this.JSONArray.Querystring;
Also whenever we want to call web methods like above example, we need to set following protocols under <webServices> in web.config file.

<webServices>
<protocols>
<add name=”HttpGet”/>
<add name=”HttpPost”/>
</protocols>
</webServices>

  1. Up to this point we have finished with development of the Ajax logic which will return a response. So now we need to develop logic for updating the HTML controls.

In this.handleResponse (step 3) we have seen that we get response in the “data” variable in JavaScript.

So now we have response from the server we will add following logic:

switch(self.JSONArray.dependentType)
{
case 0:
PopulateControls(self.JSONArray.isEdit[0].textBoxId,data);
//simple call to JS function
break;
case 1:
PopulateControls(self.JSONArray.isEdit[0].dropDownId,data);
break;
}


self.JSONArray.isEdit[0].textBoxId
will contain the id of the text box in which we need to update. And data is the response from the server. In our switch we have simply used the elements of JSON object developed in Step 2.

We will now focus on initiating a request and setting the elements of the JSON objects.

First simply create object of our AjaxClass().

var obj = new AjaxClass(); //Object creation
obj.JSONArray.Method = “GET”; //Setting Method
obj.JSONArray.isEdit[0].textBoxId=”txt1″;//Textboxid for response
obj.JSONArray.dependentType=0;//0->Textbox,1->drop downlist,
//2->tagId,3->Misc and so on
obj.init();//Initiate the AjaxCall

If obj.JSONArray.dependentType=1 then our switch case will not work for the textbox, but it will work for a dropdown list (check above switch case). This means we will have to set the dropdown in the JSON object:

obj.JSONArray.isEdit[0].dropDownId=”ddl1″;

In this way we can define our own set of HTML controls to be updated.

In the same way we can also change all the default settings in JSON object of that class.

e.g.

obj.JSONArray.Method = “GET”;
obj.JSONArray.CallPage = “Mywebservice/webMethod”;
obj.JSONArray.Querystring= “My querystring”;

For this URL will be : this.url = this.url + this.JSONArray.CallPage + this.JSONArray.Querystring ;

In case of a web service we will have to set the CallPage element as we did in the above example.

For multiple textboxes use: obj.JSONArray.isEdit[0].textBoxId=”txt1$txt2$txtn”;//$ is a delimiter
While sending data from the server send it with the same delimiter,in such a way when we split obj.JSONArray.isEdit[0].textBoxId and response data on $; we will receive data and the appropriate textBoxId.

Now that we have different types like “txtbox(es) + drop down list(s) + div” in such case we can use “misc” option of isEdit element of JSON object.

And we can define our  PopulateControls function the way we want. For ASP.NET we could also integrate ICallback logic for large data transfers.

You can download the demo code here . This contains an ASP.NET project with the following files:

  • XMLHTTPJsClass.js this file contains our AjaxClass() and funtion to populate textbox(es).
  • Demo.js this file contains 3 js function which initiates AjaxRequest with customization of  request. Here you can find web page and webservice calls.
  • Default.aspx page
  • Webservice.asmx page.


Advertisements

One Response to “Update Multiple Page Elements Using The XMLHTTPRequest Object and JavaScript”

  1. Thanks u r information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: