Building an AJAX Tree control

Recently I’ve been in need to create use a tree control that is capable of doing the following:
– Displays tree items
– Branches can be opened to see children
– The tree is dynamically built to minimize server load

I was sure that there are plenty of solutions out there that I could use. After doing some search I found that the Ext framework offers a control that would be easy to integrate and use. So if you’re interested in how to integrate the Ext tree control with an ASP.NET or PHP backend to have it work like the Ext tree sample, read on.

The client side: javascript

To use the Ext tree control I’ve included the following code.

 
		<script src="ext/ext-base.js" type="text/javascript"><!--mce:0--></script>
 
		<!-- The tree control will generate itself in this div -->
<div id="tree-div"></div>

Note that in order for the tree to display as expected you should need to have the resources/images directory accessible that ships with Ext under ext/resources/images (so that images in the tree will display correctly).
The only thing that needs to be changed is the !!!serverFileName!!! to an address that actually serves the request.

I also wanted to handle the click event and have the value selected appear in an input field. Only a little modification had to be done to the code:

 
		<script src="ext/ext-base.js" type="text/javascript"><!--mce:1--></script>
 
<input id="tree-clicked-input" style="overflow: auto; height: 400px; width: 450px; border: 1px solid #c3daf9;" type="text" />
		<!-- The tree control will generate itself in this div -->
<div id="tree-div"></div>

The server side: ASP.NET

Server side response can be created in various ways. I’ve chosen the easiest approach: using a generic handler (To do so in Visual Studio simply create an ASP.NET web application and choose to add a new Generic Handler). The code for generating the response is the following:

using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
 
namespace SenseNet.PortalEngine.PortletAPI
{
///
/// Summary description for $codebehindclassname$
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Handler1 : IHttpHandler
{
 
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write(@"[");
IList children = new ArrayList();
if (HttpContext.Current.Request.Params["node"] != null &amp;&amp; HttpContext.Current.Request.Params["node"] != "source")
{
// Has been postback
// TODO: Fill up children list
}
else
{
// No postback yet
// TODO: Get the root members
}
foreach (object child in children)
{
string childText; //TODO: assign value
string childId; //TODO: assign value
bool isChildLeaf; //TODO: assign value
string childType = "folder";
if(isChildLeaf)
childType = "file";
if (isChildLeaf) // Output for a non-leaf member
context.Response.Write(String.Concat("{\"text\":\"", childText, "\",\"id\":\"", childId, "\",\"cls\":\"", childType, "\"}"));
else // Output for a leaf member
context.Response.Write(String.Concat("{\"text\":\"", childText, "\",\"id\":\"", childId, "\",\"leaf\":true,\"cls\":\"", childType, "\"}"));
}
context.Response.Write(@"]");
}
 
public bool IsReusable
{
get
{
return false;
}
}
}
}

After creating this ashx file don’t forget to replace the !!!serverFileName!!! tag in the javascript file to point to it.

The server side: PHP

Coding the server side is PHP is even simpler than the ASP.NET version. A possible implementation is the following:

After creating this php file don’t forget to replace the !!!serverFileName!!! tag in the javascript file to point to it.