ASP.NET · C# · Dotnet · Javascript · Jquery

ASP.NET TreeView tree node icon change JavaScript/JQuery

Dear Reader,

This is my start up work on the web technologies after along standing work on windows platform. Its very much exciting to work on JS and JQuery, although still alot looks gloomy and mysterious to me and ofcourse confusing and sometimes head banging 😉

Anyways, lately i took up a small work on ASP.NET TreeView which currently the whole implementation was done at the server side. So any action on the treeview (treenode) a postback was happening which resulted in complete TreeView being built and sent back via XML from server, thus traffic is huge and so is loading times.

At the moment i have managed to do action click on any tree node without any postback as well as icon reset at the client end itself rather than complete postback from the server.

Treeview.aspx

<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”TreeView.aspx.cs” Inherits=”WebApplication1.TreeView” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;

<script src=”//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js” type=”text/javascript”></script>

<html>
<head>
</head>
<body>
<form id=”form1″ runat=”server”>
<asp:TreeView runat=”server” ID=”TreeView1″ EnableViewState=”false” EnableClientScript=”True”
Target=”form1″>
</asp:TreeView>
<div>
</div>
</form>
</body>
</html>

<script src=”TreeView.js” type=”text/javascript”></script>
<script type=”text/javascript” language=”javascript”>
$(“#TreeView1”).on(‘click’, this, OnTreeNodeClick);
</script>

As you can see i just have added a server control asp:TreeView onto the aspx page. And after that using JQuery i have attached click event for every node of the tree with node object is being passed as an argument to the delegate OnTreeNodeClick method.

Treeview.aspx.cs

public partial class TreeView : System.Web.UI.Page
{
static IDictionary<string, string> _IconimageDictionary = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (_IconimageDictionary.Count < 1)
{
_IconimageDictionary.Add(“1”, “./Resources/Image1.png”);
_IconimageDictionary.Add(“2”, “./Resources/Image2.png”);
_IconimageDictionary.Add(“3”, “./Resources/Image3.png”);
_IconimageDictionary.Add(“4”, “./Resources/Image4.png”);
}

TreeNode t = new TreeNode();
t = new TreeNode(“Parent2”);
t.ImageUrl = _IconimageDictionary[“1”];
t.ChildNodes.Add(new TreeNode(@”Parent2\Child10″){ ImageUrl = _IconimageDictionary[“1”]});
t.ChildNodes.Add(new TreeNode(@”Parent2\Child20″) { ImageUrl = _IconimageDictionary[“1”] });
t.ChildNodes.Add(new TreeNode(@”Parent2Child30″) { ImageUrl = _IconimageDictionary[“1”] });
TreeView1.Nodes.Add(t);
}
}

I am filling the dummy information from server onto the tree node for the first time only. In real life scenario, this dummy data would be fetched from DB or filesystem.

Once the server construct the HTML data of this tree and sends back to the browser, its whole different ballgame to identify the tree nodes and access them or to even modify the DOM tree. This is because .NET<4, there is no way one can set client ID for any HTML elements, since i am using 3.5 framework, the server takes privileges in setting its own Client ID for the tree node elements.

HTML Source from Browser of TreeView:

<table cellpadding=”0″ cellspacing=”0″ style=”border-width: 0;”>
<tr>
<td>
<a id=”TreeView1n0″ href=”javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,’ ‘,TreeView1n0Nodes)”>
<img src=”/WebResource.axd?d=cZ5kMITeSm_Rn7tikwjob9p_LS9v3TCcc3ApPfN2ItF2ekZYXvhU3yEijLo8a3AAWHN2L0l2O32tJJ79rAu9e4UXdJuLimPPMUSMFc54G6IwB09f0&amp;t=635199992887188881″ alt=”Collapse Parent2″ style=”border-width: 0;” />
</a>
</td>
<td>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t0’);” id=”TreeView1t0i” tabindex=”-1″>
<img src=”./Resources/Image1.png” alt=”” style=”border-width: 0;” />
</a>
</td>
<td style=”white-space: nowrap;”>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t0’);” id=”TreeView1t0″ style=”text-decoration: none;”>Parent2</a>
</td>
</tr>
</table>
<div id=”TreeView1n0Nodes” style=”display: block;”>
<table cellpadding=”0″ cellspacing=”0″ style=”border-width: 0;”>
<tr>
<td>
<div style=”width: 20px; height: 1px”>
</div>
</td>
<td>
<img src=”/WebResource.axd?d=D6-CBDozPvT6cSNuEIYsRXO5GdTG2ybgi40r8UfRPOR_FwCtOjk_rm_jbNDblYlDLwgKA-ihR41amS8iiChAic99j1mJhhEaU0jqBXw4JSA3lDt70&amp;t=635199992887188881″ alt=”” />
</td>
<td>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2\\Parent2*|*Child10′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t1’);” id=”TreeView1t1i” tabindex=”-1″>
<img src=”./Resources/Image1.png” alt=”” style=”border-width: 0;” />
</a>
</td>
<td style=”white-space: nowrap;”>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2\\Parent2*|*Child10′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t1’);” id=”TreeView1t1″ style=”text-decoration: none;”>Parent2\Child10</a>
</td>
</tr>
</table>

As you can see, the treeview is translated into bunch of <tr> <td> tags. So now, i need to change the image icon of each tree node to something else apart from what the server has set already.

Here comes the JQuery|JavaScript to the rescue. Since its all new and beginning to me, it took a while for me to understand the whole javascript jquery API and its working style. So based on the basic understanding, i could come up with the below code:

Treeview.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function OnTreeNodeClick(sender) {
    var id =sender.target.id;
    if (id) {
        var doc = document.getElementById(id);
        var innerhtml = document.getElementById(doc.id + 'i').innerHTML;
        innerhtml = innerhtml.replace("Image1.png", "Image2.png");
        document.getElementById(doc.id + 'i').innerHTML = innerhtml;
    }
    return false;
}

As per the above code, i am passing the ‘this’ as an second argument from aspx ‘on’ method call of JQuery. So the sender argument will be the treenode on which the user has clicked on. Once i get the sender, i need to find the server generated client ID for this node. Once i get the id, i get the DOM element via getElementById() API in line 4.

If you refer the server generated HTML document for browser pasted above, you can see that for each tree node there are 3 <td> tags per <tr>. So looking a bit deeper, we noticed that one <td> is for icon and other for the text element of the particular tree node. Thankfully ASP.NET consistently appends “i”  to the end of the clientID for identifying it as icon element in the treenode.

So in the line 5, i get the innerHTML  of that icon tag for that particular treenode by appending “i” to the id of the sender tree node. In line 6, i replace the png name to the required name. Then in line 7, i assign it back to the innerhtml for the DOM tree to refresh itself. Line 9 is important to avoid any postback happening.

Theres still more to learn and more validation, requirements to be added and the source code needs alot of beatification to improve it.

Please feel free to submit any suggestions.

Thanks,
Zen 🙂

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

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