| Summary: This tutorial describes how to use EXTJS Tree Panel with ASP.NET 2.0. It includes a sample website completely developed in ASP.NET, C# and javascript. This example will demonstrate how to get the ext tree working in ASP.NET and how to populate nodes on demand. |
| Author: Muhammad Irfan Ali Qureshi |
| Published: Dec 10, 2008 |
| Ext Version: v2.2 |
Languages: English
|
Contents |
I have been using ASP.NET built-in Tree control for a while, but there are quite many issues with it, especially when you try to put some ajax on your pages. ASP.NET's tree control was not designed to work with AJAX and there is no easy way you can populate the tree nodes on demand (e.g. by using Page Methods or web services; two light-weight techniques when ajaxifying your asp.net applications).
In addition, the tree control of ASP.NET hurts my aesthetic sense when it renders itself. These are the two reasons I started to use EXT's treepanel. However, I could not find much contents or any tutorial about how to use it with ASP.NET. There is plenty of stuff about PHP, though. So, I am writing this tutorial just to share my experience with the fellow developers.
In this article, We'll be developing a hierarchy of my dummy company's dumb employees (oh.. Did I say dumb instead of dummy!). It will show the managers/supervisors as expandable nodes, and subordinates having no other subordinate as the Leaf nodes. The managers will be expanded on demand, and this will make our html light weight.
We'll develop two pages: One to contain the tree panel and the other to provide the tree nodes. On the second page (let's call that Tree Loader), we'll get the id of the parent node being expanded. However, there will be no parent ID when the top level parent is being expanded on page load.
The technique we'll see in this article is almost similar as the one in Reordering Tree Example. However, instead of PHP, the server side language is ASP.NET. Also, for demonstration, I added only the tree CSS class and images in the website.
To start with, let's open Visual Studio 2005, and create a new website. It will add Default.aspx page to the website. On that page, just drag drop one HTML div and give it ID say, "divEmployees". On the same page, let's edit the source add a small script tag, and add the js to render the tree in divEmployees. The page contents will be something like this:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Organization Chart</title> <link href="css/tree.css" rel="stylesheet" type="text/css" /> <script src="scripts/ext-base.js?v=1.0" type="text/javascript"></script> <script src="scripts/ext-all-debug.js" type="text/javascript"></script> </head> <body> <script language="javascript" type="text/javascript"> Ext.onReady(function(){ var Tree = Ext.tree; tree = new Tree.TreePanel({ el:'divEmployees', useArrows:true, autoScroll:true, animate:true, enableDD:false, containerScroll: true, dataUrl: 'TreeLoader.aspx', root: { nodeType : 'async', text : 'Employees', visible : false, id : 'source' } }); // render the tree and expand the parent node tree.render(); tree.getRootNode().expand(); }); </script> <div id="divEmployees" style="width: 350px; height: 600px"> </div> </body> </html>
As shown in the above asp.net script. we'll use TreeLoader.aspx as the data loader page. To do so, we'll add a new page in our website and name it TreeLoader.aspx. Since, this will have to contain only the nodes data and no other HTML, we'll omit all the html and add just one Literal control. The asp.net script would look like this for TreeLoader.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TreeLoader.aspx.cs" Inherits="TreeLoader" %> <asp:Literal ID="Literal1" runat="server"></asp:Literal>
Then in the Code Behind file for TreeLoader, we'll add the following code:
using System; using System.Data; using System.Data.SqlClient; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class TreeLoader : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { int selectedID = 0; if (Request.Form.Count != 0 && Request.Form[0] != "source") Int32.TryParse(this.Request.Form[0], out selectedID); this.Literal1.Text = GetNodes(selectedID); } private string GetNodes(int SupervisorID) { System.Text.StringBuilder returnValue = new System.Text.StringBuilder(); String Query = "SELECT emp.EmployeeID, " + " emp.FirstName + ' ' + emp.LastName AS EmployeeName, " + " CAST(CASE WHEN a.Subordinates > 0 THEN 1 ELSE 0 END AS BIT) IsSupervisor " + "FROM Employee emp WITH(NOLOCK) LEFT JOIN " + " (SELECT sup.SupervisorID, COUNT(*) Subordinates " + " FROM Employee sup WITH(NOLOCK) " + " GROUP BY sup.SupervisorID ) a ON a.SupervisorID = emp.EmployeeID " + "WHERE IsNull(emp.SupervisorID, 0) = " + SupervisorID.ToString(); DataSet myDataSet = new DataSet(); string connectionString = ConfigurationManager.ConnectionStrings["EmployeesDatabase"].ConnectionString; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(Query, connection); mySqlDataAdapter.Fill(myDataSet); } DataTable employees = myDataSet.Tables[0]; string isLeaf = string.Empty; bool isSupervisor = false; for (int i = 0; i < employees.Rows.Count; i++) { DataRow dr = employees.Rows[i]; returnValue.Append( "{\"id\": \"" + dr["EmployeeID"].ToString() + "\"," + "\"text\": \"" + dr["EmployeeName"].ToString() + "\","); isSupervisor = Convert.ToBoolean(dr["IsSupervisor"].ToString()); if (isSupervisor) isLeaf = "false"; else isLeaf = "true"; returnValue.Append("\"leaf\": " + isLeaf + "}"); if (i < employees.Rows.Count - 1) returnValue.Append(","); dr = null; } return "[" + returnValue.ToString() + "]"; } }
As you can see, we are fetching the parent node's ID in page load event. ASP is behaving in a manner like EXT tree is submitting requests to TreeLoader.aspx and the request data exist in Form variables. However, when the top-level parent is rendered, there is no form variable. In case you need to display the subordinates of a particular employee on page load, you can send that employee's ID in Query string, etc, and process it accordingly.
In the GetNodes method, we are querying database and building the string for Literal control Text. Here is the output of this example:
Those of you who are wondering about the database, here you can Download DB Script for the table being used. (Note that it only contains dummy data.) And here is the complete source of the website Download Complete Solution.
--IrfanQureshi 13:22, 10 December 2008