Click here to Skip to main content
15,879,490 members
Articles / Web Development / IIS

Building a TreeView on Demand Using AJAX

Rate me:
Please Sign up or sign in to vote.
3.19/5 (11 votes)
27 Nov 2006CPOL4 min read 97.9K   1.1K   56   10
A simple implementation of AJAX in generating a tree view from XML, ASP.NET, and C#.

Sample Image - ajaxtreeview.gif

Introduction

AJAX, or Asynchronous JavaScript and XML, is a free framework for quickly creating a new generation of more efficient, more interactive, and highly-personalized web experiences that work across all the most popular browsers. AJAX is a relatively new phenomenon, based on technologies that aren't quite new, for creating a way for businesses to interact with customers over the internet.

In this article, we use the current AJAX technique (in its simplest way) to implement an on-demand tree view. Since XML is a common standard and easy to implement, I am using XML in my sample application instead of a database. I have found another article here to build a tree view using AJAX.

History (Skip this section if you are feeling bored)

This technology was introduced first by Microsoft (from my best knowledge) back in 1999, and had been known as "DHTML / JavaScript web application with remote calls". The whole idea of the technology was to allow an internet browser to make an asynchronous HTTP call to remote pages/services and update a current web page with the received results without refreshing the whole page. In the creator's opinion, this should have improved the customer experience, making HTTP pages look and feel very similar to Windows applications.

Because the core implementation of this technology was based on internet browser functionality, the usability was very limited at that time. Several years later, the technology was reborn with new browser support and massive implementation by such giants as Google, Amazon.com, eBay, etc.

Today, it's known as AJAX, and considered as a natural part of any dynamic web page with advanced user experience. Many readymade frameworks are also available on the internet like Microsoft AJAX/ATLAS and Enterprise AJAX.

Why AJAX

This sample application provides a tree view implementation from an XML file. In real scenarios, I have noticed the processing of building the complete tree structure (with many level children) and rendering into the browser takes quite a long time. I attempted different approaches, one of them was building the tree on demand. But I don't like the post back (I am sure you too). Then I found AJAX was the best bet. By this, we could avoid a post back and flickering of the browser; we're just changing the portion of the page, hence reducing the traffic in the server and enhance the performance.

Working

The idea is to build a tree structure using UL and LI tags and use a style sheet and some JavaScript, all together giving some real effects. On page load or a pre-render event, the root node will be loaded; from that, on click of the plus/minus images, you can expand or collapse the tree. You can notice that the child node is generated on the fly (of course, you can cache the data source). Since AJAX is asynchronous, I am displaying an image to indicate that a request is already made to the server.

Implementation

The code files include:

  • TreeSource.XML: The source file where the tree structure is defined.
  • XML
    <?xml version="1.0" encoding="utf-8" ?>
    <Nodes>
      <Node NodeID="0" NodeName="World" ParentID="-1"></Node>
      <Node NodeID="1" NodeName="North America" ParentID="0"></Node>
    <Node NodeID="13" NodeName="United States" ParentID="1"></Node>
  • AJAXroutine.js: The JavaScript file contains all the required methods to handle the asynchronous calls and the standard AJAX methods. JavaScript is the core component in this technology, as you can see. It handles the change detection, data request receipt, and placing of the data on the page.
  • JavaScript
    //To toggle the node image and expand collapse
    function Toggle(node){
    
      // Unfold the branch if it isn't visible
      if (node.nextSibling.style)   {           
            if (node.childNodes.length > 0)     {
                  if (node.childNodes.item(0).nodeName == "IMG"){
             ...

The core function for the asynchronous request is:

JavaScript
//The core function to get the xml http request object
function GetXmlHttpObject(){ 
  var objXMLHttp=null
  if (window.XMLHttpRequest){
        ...

The HTML will look like the following tags:

HTML
<ul id="treeUL" class="treeUL">
  <li id='10'>
  <span title='World' valign='bottom' 
    onclick="javascript:if (Toggle(this))showContentsEx('divTree0','0','');">

The client SPAN will call the following function to invoke the server request:

JavaScript
/***********************************************************
//Builds the query string and invoke a request to the server 
//using javascript async call
/***********************************************************/
function showContentsEx(div, str, lmsg){ ...
  • WebForm1.aspx: The sample .aspx file. It has the root level hard-coded in this sample. I have put some styles to make it look nice. You can build that section on the fly.
  • WebForm1.aspx.cs: The code behind of the .aspx file.
  • GetTreeContents.aspx: Empty in the design mode.
  • GetTreeContents.aspx.cs: All the client requests process this code-behind and renders in the browser. When the client HTTP request is made, the following scripts will execute on the server and render the HTML on the browser.
C#
private void Page_Load(object sender, System.EventArgs e)
{           
    if (!IsPostBack)
    {
        //id passed thro' the url query string
        string key = Request.QueryString["q"]; 

        if (key != null)
        {
            //read the xml tree file from the web.config file 
            //add the following key in web.config
            //<appSettings>
            //<add key="XmlTree" value="~/TreeSource.XML" />
            String path = Server.MapPath(ConfigurationSettings.AppSettings["XmlTree"]);

            //I use XmlDocument object here to manipulate Xml- You can use other objects
            //You can cache the XmlDocument.OuterXml string
            XmlDocument xmlTree = new XmlDocument();
            xmlTree.Load(path);
            System.IO.StringReader xmlSR = new System.IO.StringReader(xmlTree.OuterXml);

            //If you want to use database driven tree you skip above codes
            //but the columns should be there in the data table
            DataSet ds = new DataSet();
            ds.ReadXml(xmlSR);
            DataView dv = ds.Tables[0].DefaultView;

            //filter for the parent
            dv.RowFilter = " ParentID = '" + key + "'";

            //render the brower with a <UL> tag and <LI> list
            //I have used some styles
            Response.Write ("<ul class='wTreeStyle'>"); 

            //write all the children here
            for(int i=0; i < dv.Count; i++)
            {     
                //formatted <LI> tag - 
                Response.Write (string.Format("<li id='{0}'><span valign='bottom' " + 
                      "title='{1}' onclick=\"javascript:if (Toggle(this))" + 
                      "showContentsEx('divTree{0}','{0}','');\"><IMG  " + 
                      "align='bottom' SRC='plus.gif'> <span class='treeStyleNode' >" + 
                      "{1}</span></span><span id ='divTree{0}'></span></li>", 
                      dv[i]["NodeID"].ToString(), dv[i]["NodeName"].ToString())); 
            }
            Response.Write ("</ul>"); 
        } ...
  • Images: Loading.gif, plus.gif, minus.gif
  • Web.config: for the key
XML
<add key="XmlTree" value="~/TreeSource.XML" />

For simplicity, I am putting only the required code since I want to share the implementation; you can customize this or enhance it in your projects.

Conclusion

This article is aimed at illustrating the simplicity of using AJAX technology in any ASP.NET application. It is up to developers who want to use the technology in this way. I just did a practical implementation of the technology since the core code is already in place. I have tested the application in MS Visual Studio V.7/ MDE 2003 and MS .NET Framework 1.1. And C# - ASP.NET.

Credits

With the help of God, I am submitting this article here. I would like to thank the Codeproject.com community and some other information web sites for providing a great service. I also thank my colleagues and friends for their support, cooperation, and reviewing this article.

You can download the files, and I hope it is a completely working one. Most readers (I am one of them) want a good sample to start with. I tried my best for the cause. I hope you will enjoy this simple implementation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
AJFK (Abduljaleel Faisel kakkidi) is an IT Consultant in US. He has been developing and designing MS Client server and Web solutions since 1997. His expertise lies in developing scalable, high-performance Web solutions for various fields. Hobbies include teaching, and reading books. AJ Kakkidi has a Bachelor of Physics, and Masters of Computer Applications. He can be reached at ajkakkidi at yahoo.com.

Comments and Discussions

 
QuestionThis is not fully covered. Pin
christhuxavier17-Oct-13 3:10
christhuxavier17-Oct-13 3:10 
Questionurl? Pin
ninja_scroll9-Nov-07 5:27
ninja_scroll9-Nov-07 5:27 
NewsFix for firefox. Pin
LanUx3-Jun-07 16:22
LanUx3-Jun-07 16:22 
I did some hunting and i'll explain the fix but here it is first.

function Toggle(node){<br />
	// Unfold the branch if it isn't visible<br />
	if (node.nextSibling.style)	{	<br />
		if (node.childNodes.length > 0)	{<br />
			if (node.childNodes.item(0).nodeName == "IMG"){<br />
				if(node.childNodes.item(0).src.indexOf("plus.gif")> -1){<br />
					node.nextSibling.style.display = 'block';<br />
					node.childNodes.item(0).src = "minus.gif";<br />
					return true;<br />
				}<br />
				else {<br />
					node.nextSibling.style.display = 'none';<br />
					node.childNodes.item(0).src = "plus.gif";<br />
					return false;<br />
				}				 <br />
			}<br />
// If firefox, check a different childnode<br />
			else if (node.childNodes.item(1).nodeName == "IMG"){<br />
				if(node.childNodes.item(1).src.indexOf("plus.gif")> -1){<br />
					node.nextSibling.style.display = 'block';<br />
					node.childNodes.item(1).src = "minus.gif";<br />
					return true;<br />
				}<br />
				else {<br />
					node.nextSibling.style.display = 'none';<br />
					node.childNodes.item(1).src = "plus.gif";<br />
					return false;<br />
				}				 <br />
			}<br />
		}		<br />
	}<br />
}


Firefox uses a different COM structure so node.childNode.item(0).nodeName equals "IMG" in IE but "#text" in firefox. So i added an extra if case and tada.
GeneralRe: Fix for firefox. Pin
mohammad tavakoli10-Nov-07 3:18
mohammad tavakoli10-Nov-07 3:18 
GeneralHi all Pin
achille2k25-Apr-07 21:30
achille2k25-Apr-07 21:30 
Generalnot work on mozilla Pin
LeleHalfon8-Mar-07 13:15
LeleHalfon8-Mar-07 13:15 
GeneralBuilding Tree View using xml file Pin
anmolgupta7-Mar-07 3:01
anmolgupta7-Mar-07 3:01 
GeneralWorking in Mozilla Pin
~~Atul~~11-Feb-07 20:53
~~Atul~~11-Feb-07 20:53 
GeneralRe: Working in Mozilla Pin
Mikudi28-Mar-07 22:05
Mikudi28-Mar-07 22:05 
GeneralGood work Pin
~~Atul~~7-Feb-07 20:05
~~Atul~~7-Feb-07 20:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.