Page Load with AJAX & XML

With the arrival of AJAX, lots of things have improved as well as it also adds interactivity and fanciness in your applications.

Here it is about no rocket science but an interesting scenario, that is to display the data received from the web service in the XML format the AJAX way during the page loading of a website.

Scenario : -

I've a web service, which returns a XML data. The requirement is to display that XML in tabular format during the page_load of your web site as well as with the AJAX style of fanciness with some update progress animations etc. 

There were two reasons for which I had to go with the client side script rather than returning a dataset and binding it with a GridView.

First was that a I was unable to find way to control or manipulate a DataSet through javascript, and second was that it is something about incremental page load which involve AJAX style loading of the page involving update progress animation, and hence requires a client side script to come into action.

Lets start with a simple web service which returns XML records, Here's the code which I did

Imports System.Data
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<System.Web.Script.Services.ScriptService()> _
Public Class WebService
    Inherits System.Web.Services.WebService
    <WebMethod()> _
    Public Function getIndianTeam() As String
        Dim ds As New DataSet
        System.Threading.Thread.Sleep(2000)
        ds.ReadXml(Server.MapPath("App_Data/IND.xml"))
        Return ds.GetXml()
    End Function

    <WebMethod()> _
    Public Function getPakistanTeam() As String
        Dim ds As New DataSet
        System.Threading.Thread.Sleep(4000)
        ds.ReadXml(Server.MapPath("App_Data/PK.xml"))
        Return ds.GetXml()
    End Function
End Class


Note: In my application, I'm retreiving the records (into the DataSet) from the database though, but here I'm reading an XML file rather (for example purpose).
Another thing to notice is that you need to add  

"Imports System.Web.Script.Services"

statement on the top of your code file in the webservice. as well as the following code

"<System.Web.Script.Services.ScriptService()> _"

which can be seen in the code given above. These two statements are not by-default part of the code, when you add a new webservice page into your project.
We are going to consume the web service in the default.aspx page.


The image above describes you what you need to do in your default.aspx page. I've placed an HTML Table with four rows. Row1 and Row3 has labels with headings "Pakistan Team" and "Indian Team" respectively. Row2 and Row4 has Label controls as well as an animated GIF (can be of your choice) which will act as what the name suggests the Update Progress animation.

Also note that the cell at Row2 and that of Row4 has been named as "tdPak" and "tdInd" respectively.

For this example, I've placed two XML files PK.xml and IND.xml inside the App_Data folder of the project. following image shows the solution explorer with the complete file and directory structure of this project.

Next thing we need to do is to write client side code which will interact with the webservice. Before doing that select the Script Manager in the design mode of your default.aspx file and click on properties (or press F4) and click on the Service Collection, which will open up the following window.



Click the Add button to add a new service reference to your Script Manager, this will enable you to use the web service in your code. Also since the webservice.asmx file is a part of your project, hense there's no need to write the whole path i.e. http://www.xyz.com/services/myservice.asmx etc. but you may only specify the name of the webservice file that is webservice.asmx.

Now you are able to use the webservice in your client script. Here's what we need to do now.

<head runat="server">
    <title>AJAX With XML</title>
    <LINK rel="stylesheet" type="text/css" href="StyleSheet.css" />
    <script language="javascript">
        function pageLoad() {
        vResult = WebService.getPakistanTeam(onRetreivePK,onError);
        vResult = WebService.getIndianTeam(onRetreiveIN,onError);        
        }
        
        function onRetreivePK(vResult){
            loadXML(vResult,1);
            }
            
        function onRetreiveIN(vResult){
            loadXML(vResult,2);
            }
            
        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        function loadXML(xmlString,obj) { 
          xmlDoc.async="false";
          xmlDoc.onreadystatechange=verify;
          xmlDoc.loadXML(xmlString);
          displayXMLGrid(xmlDoc,obj);
        }
        
        function displayXMLGrid(xmlDoc,obj) {
            var root = xmlDoc.firstChild;
            var i=0;
            var strResult="<table border='0' style='width:100%'>";
            var tClass = "tdA";
            
            if (root.hasChildNodes) {
                var v = root.childNodes[0];
                while (v != null) {
                    v = root.childNodes[ i ];
                    if      (v==null) break;
                    if (tClass=="tdA") tClass = "tdB";
                    else tClass = "tdA";
                    
                    strResult +="<tr>";
                    strResult +="<td class='" + tClass + "'>" + v.attributes[0].text + "</td>";
                    strResult +="<td class='" + tClass + "'>" + v.attributes[1].text + "</td>";
                    strResult +="</tr>";
                    i++;
                    }                    
                }
                strResult += "</table>";
                
                if      (obj==1)    document.getElementById("tdPak").innerHTML=strResult;
                else if (obj==2)    document.getElementById("tdInd").innerHTML=strResult;
            }
            
        
        function verify() {
          // 0 Object is not initialized // 1 Loading object is loading data // 2 Loaded object has loaded data
          // 3 Data from object can be worked with // 4 Object completely initialized
          if (xmlDoc.readyState != 4) {
            return false;
          }
        }        
        function onError(vResult){  alert(vResult);  }
    </script>
</head>

In the above code, as you can see that I'm calling the Webservice methods to retreive the data in the form of XML. while the function calls have two arguments one is OnRetreivePK and second is OnError. These are basically sub routines ( or events ) rather than arguments, telling the method call that to call the OnRetreivePK method upon successfully receiving data and go to the OnError event if some error occurs.

I've used Microsoft.XMLDOM class with couple of methods of it to iterate through the nodes of the XML data retreived which very easy to understand, and then populating the cells of the table depending on the argument received.



Your application is ready to perform now.
You can now run the application and it will show up with some nice and fancy style loading that is light weight as well as faster.

You can download the source code by clicking on the Following link. AJAXWeb2.zip

Happy Coding & Regards - raheel
Published Monday, December 03, 2007 4:01 AM by Raheel Hussain

Comments

No Comments
Powered by Community Server (Non-Commercial Edition), by Telligent Systems