<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code Pencil</title>
	<atom:link href="http://www.codepencil.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codepencil.com</link>
	<description>Manu Mahajan`s blog</description>
	<lastBuildDate>Tue, 14 Apr 2009 16:15:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cheers to FOSS.IN</title>
		<link>http://www.codepencil.com/index.php/cheers-to-fossin/</link>
		<comments>http://www.codepencil.com/index.php/cheers-to-fossin/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 18:02:06 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[foss.in]]></category>
		<category><![CDATA[weblog]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/index.php/cheers-to-fossin/</guid>
		<description><![CDATA[FOSS.IN started yesterday! I&#8217;m really excited about the event even though I&#8217;m not attending it this time. I was there last year and it was a great experience. Ever since then, I&#8217;ve been really eager to step into the open source world with some contribution but somehow this whole year has been crazy for me [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://foss.in">FOSS.IN</a> started yesterday! I&#8217;m really excited about the event even though I&#8217;m not attending it this time. I was there last year and it was a great experience. Ever since then, I&#8217;ve been really eager to step into the open source world with some contribution but somehow this whole year has been crazy for me in terms of work and other personal events and I couldn&#8217;t move significantly towards that goal of mine.</p>
<p>FOSS.IN has always focused on contribution but this year they are taking it a step further and there will be less talks and more code. There are a set of Workouts planned and people will come prepared with a goal in mind, and code together on the spot.</p>
<p>So in the spirit of the FOSS.IN workouts I&#8217;ve decided that these five days (actually nights since I&#8217;m working during the days) I&#8217;ll spend all the time that I can and try to put in some contribution from my side. I hope to explore the java-gnome bindings and use them to write my first application for GNOME.</p>
<p>So even though I&#8217;m not going to the event I&#8217;ll hopefully be taking my first steps towards contributing to FOSS <img src='http://www.codepencil.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>I spent the first night exploring java-gnome and starting with my application. I will write about the java-gnome experience in my next post. But for now it&#8217;s back to coding&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/cheers-to-fossin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thoughts On Developing A CSS Strategy</title>
		<link>http://www.codepencil.com/index.php/thoughts-on-developing-a-css-strategy/</link>
		<comments>http://www.codepencil.com/index.php/thoughts-on-developing-a-css-strategy/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 18:30:10 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/index.php/thoughts-on-developing-a-css-strategy/</guid>
		<description><![CDATA[While planning for an upcoming project at my workplace I&#8217;ve had to think about developing a CSS strategy for a web application. I&#8217;ve never spent so much time thinking about the presentation layer since we are generally more concerned with the business logic and the back-end but this time we need to create a site [...]]]></description>
			<content:encoded><![CDATA[<p>While planning for an upcoming project at my workplace I&#8217;ve had to think about developing a CSS strategy for a web application. I&#8217;ve never spent so much time thinking about the presentation layer since we are generally more concerned with the business logic and the back-end but this time we need to create a site that is very different from previous projects that we&#8217;ve done. </p>
<p>So the idea is to create a web site that uses the so called <strong>best practices</strong>:</p>
<ul>
<li>Semantic HTML</li>
<li>Separation of content and markup</li>
<li>Cross browser support</li>
<li>Search engine friendliness</li>
</ul>
<p>And everything else that a modern web site should have.</p>
<p><span id="more-13"></span></p>
<h2>Why a CSS strategy?</h2>
<p>The problem is simple &#8211; A big web site with multiple developers working on it simultaneously along with their individual coding styles. </p>
<p>There needs to be a set of guidelines for everyone to follow. At a bare minimum you need consistency in coding and (a sense of) ease of maintainence. Anything above that (like good readability) is a bonus.</p>
<p>For me I don&#8217;t know what is more readable &#8211; hundreds of lines of CSS code or a couple of dozen tables nested inside each other. I&#8217;ve seen both and I&#8217;ve pulled my hair out trying to debug seemingly trivial issues.</p>
<p>CSS is not like any other programming language where you have standard design patterns or best practices to refer to. Quite often there are a zillion ways to do the same thing. You could chose between using external stylesheets or inline styles; If you use external stylesheets you need to organize them effectively; You could define selectors for ids or classes or for html elements; You could use nested styles based on multiple things; You need hacks to support older browsers and so on&#8230;</p>
<h2>What will be the components of my CSS strategy?</h2>
<p>There are multiple challenges involved in a project like this. The ones that I can think of at the moment are</p>
<ol>
<li><strong>CSS framework</strong> &#8211; Is there need to use an external CSS framework or should one build everything from scratch.</li>
<li><strong>Organisation of CSS code</strong> &#8211; It is a matter of time that your CSS code will grow and if you&#8217;re building a big site with complex styling you will need a strategy to organize your CSS files.</li>
<li><strong>Guidelines for coders</strong> &#8211; There needs to be a set of rules for consistency and for efficiency (code reuse, tackling common problems etc.)</li>
<li><strong>Workflow definition</strong> &#8211; Can a coder modify a file that is used globally and where a simple change might impact the whole site? At what level should new styles be added?</li>
<li><strong>CSS hacks</strong> &#8211; Sooner or later you face a situation where you need to apply browser specific hacks. This is definitely a last resort but you need have a plan to tackle such issues.</li>
</ol>
<p>I do not know the answers to these questions yet but I have some vague ideas forming in my head based on some resources on the web and my instincts. Let&#8217;s see how they develop over the next few days.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/thoughts-on-developing-a-css-strategy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SPAM Menace</title>
		<link>http://www.codepencil.com/index.php/spam-menace/</link>
		<comments>http://www.codepencil.com/index.php/spam-menace/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 18:41:46 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[weblog]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/index.php/spam-menace/</guid>
		<description><![CDATA[I&#8217;ve had my email address on a public web page for many years. It goes without saying that I get hundreds of mails in a day that I don&#8217;t want. I could live with that but recently I&#8217;ve been getting spam mails of a different kind.
I am constantly getting Delivery Status Notification(Failures) from so many [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had my email address on a public web page for many years. It goes without saying that I get hundreds of mails in a day that I don&#8217;t want. I could live with that but recently I&#8217;ve been getting spam mails of a different kind.</p>
<p>I am constantly getting Delivery Status Notification(Failures) from so many email servers. It seems that some stupid spammers are sending emails with fake addresses that seem to be originating from my domain(knowyourraga.com). And so if an email address does not exist a failure mail is sent to back to the address which appears to be from my domain and I happen to get all the messages send to that domain in the catch-all mailbox(which is also my primary mailbox). </p>
<p>I have tried various tests to confirm that my domain is not an open relay and I mention it here because if anyone out there can find a weakness in my server than I could correct that. I am getting hundreds of failure notification messages in a day which means that someone is sending thousands or millions of messages appearing to come from my domain. This is scary! I have no clue how to tackle this <img src='http://www.codepencil.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/spam-menace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sakai Development Diary &#8211; Getting Started</title>
		<link>http://www.codepencil.com/index.php/sakai-development-diary-getting-started/</link>
		<comments>http://www.codepencil.com/index.php/sakai-development-diary-getting-started/#comments</comments>
		<pubDate>Thu, 31 Jan 2008 12:48:38 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[sakai]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/index.php/sakai-development-diary-getting-started/</guid>
		<description><![CDATA[I&#8217;ve been playing around with Sakai for the last few days. Sakai calls itself a &#8216;Collaborative Learning Environment&#8217; and is much more than a typical LMS system. I don&#8217;t want to get into describing the project but you can read about it here
www.sakaiproject.org
It&#8217;s a pretty large project and to be able to understand how things [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with Sakai for the last few days. Sakai calls itself a &#8216;Collaborative Learning Environment&#8217; and is much more than a typical LMS system. I don&#8217;t want to get into describing the project but you can read about it here<br />
<a href="http://www.sakaiproject.org">www.sakaiproject.org</a></p>
<p>It&#8217;s a pretty large project and to be able to understand how things work you need to work with a lot of different things like tomcat, maven, spring, hibernate, jsf and many design patterns <img src='http://www.codepencil.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It took me a while to get used to the terminology and different elements that make up the project. In this post I&#8217;m describing my effort in setting up a development environment which could be the starting point for any development effort and the various useful links that I came across while searching for information. </p>
<p><span id="more-11"></span></p>
<h2>Development Environment Set Up</h2>
<p>Sakai 2.4 is the stable version but I decided to go for 2.5 which is in development and brings in a lot of new features. There is a very useful page which describes most of the stuff that&#8217;s required but there are some small things that have the potential to make you want to pull your hair out when things don&#8217;t work. I suggest you read the comments at the bottom of the page very carefuly.<br />
<a href="http://bugs.sakaiproject.org/confluence/display/BOOT/Development+Environment+Setup+Walkthrough">http://bugs.sakaiproject.org/confluence/display/BOOT/ Development+Environment+Setup+Walkthrough</a></p>
<p>Another, simpler way to start could be to have a look at this screencast by Zach Thomas of Aerpolane Software<br />
<a href="http://aeroplanesoftware.com/wordpress/wp-content/uploads/2008/01/developing-for-sakai-getting-started960x540.mov">aeroplanesoftware.com/wordpress/wp-content/uploads/2008/01/ developing-for-sakai-getting-started960&#215;540.mov</a></p>
<p>I set-up everything on an ubuntu machine based on the above guide and here are a few things that bugged me:-</p>
<ul>
<ol><b>Java 1.6 does not work</b> &#8211; I had Sun jdk 6 installed but sakai doesn&#8217;t yet support java 1.6 so I had to set-up java 1.5 as my primary jvm. (Particularly, I got compile errors with java 6)</ol>
<ol><b>Tomcat 5.5 tar/zip version only</b> &#8211; Make sure you download and install the Tomcat zip or tar version which can unzipped into a folder. It&#8217;s necessary to have a separate tomcat just for running sakai. </ol>
<ol><b>No Spaces</b> &#8211; For windows users it is VERY IMPORTANT to not have spaces in the paths to jdk, tomcat and the maven repositories. I tried running the demo on a Windows machine which had a jdk installed in the default location(C:\Program Files\Java\&#8230;) and I started getting a lot of exceptions all over the site</ol>
<ol><b>&#8220;mvn clean install sakai:deploy&#8221;</b> is not same as <b>&#8220;mvn clean install + mvn sakai:deploy&#8221;</b> &#8211; I don&#8217;t know why this happens but sometimes after changing code if i run <em>mvn clean install sakai:deploy</em> it doesn&#8217;t work and I don&#8217;t see code getting updated in tomcat but running the 2 commands separately always works.</ol>
<ol><b>Memory</b> &#8211; Default memory settings for either of eclipse,tomcat or maven are not going to work so you need to make sure you give them all a high amount of RAM as described in the guides above or you will start getting java.lang.outOfMemory errors. For development purposes I found that running tomcat from within eclipse saves you a lot of RAM instead of running them both in separate virtual machines.</ol>
</ul>
<p>One thing that I had trouble with in particular, was trying to add the projects to ecplise. Eclipse did not recognize individual projects and kept showing the whole code as one large project. I had to add each sub project individually. I faced this problem with code downloaded from the &#8216;trunk&#8217;. After that I downloaded the &#8216;beta2&#8242; tag from subversion and the problem did not arise with that.</p>
<h2>Debugging</h2>
<p>If you are setting up a development environment sooner or later you will need to be able to debug the code in some way. And especially with this project because of the time that is required to restart the server every time you make a change in the code. On my laptop tomcat takes about 4 mins to restart.</p>
<p>There are various approaches available for debugging. The following page describes them in detail.<br />
<a href="http://bugs.sakaiproject.org/confluence/display/BOOT/Debugging+Tomcat+Remotely+Using+Eclipse">http://bugs.sakaiproject.org/confluence/display/BOOT/ Debugging+Tomcat+Remotely+Using+Eclipse</a></p>
<p>For me the third approach in which tomcat is set up as a server within eclipse seems to work best on an ubuntu system. I have also found that when you run tomcat from within eclipse you need less amount of total RAM. So I&#8217;d recommend this approach unless you have tomcat and eclipse on separate machines.</p>
<h2>Sakai Tools</h2>
<p>Sakai Tools are responsible for generating user interfaces. If you download the source code you will see a couple of projects in the samples folder namely &#8211; </p>
<ul>
<li>sample-tool-jsf</li>
<li>sample-tool-servlet</li>
</ul>
<p>Studying these tools seems to be a good way to start exploring. I haven&#8217;t used jsf in any of the projects that I&#8217;ve worked with so it that&#8217;s one new thing to learn in the next few days <img src='http://www.codepencil.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I will post more about my encounters with sakai in the next few days.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/sakai-development-diary-getting-started/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://aeroplanesoftware.com/wordpress/wp-content/uploads/2008/01/developing-for-sakai-getting-started960x540.mov" length="17987984" type="video/quicktime" />
		</item>
		<item>
		<title>Ubuntu Gutsy Gibbon On HP tx1000 Laptop</title>
		<link>http://www.codepencil.com/index.php/installing-ubuntu-gutsy-gibbon-on-my-hp-tx1003au-laptop/</link>
		<comments>http://www.codepencil.com/index.php/installing-ubuntu-gutsy-gibbon-on-my-hp-tx1003au-laptop/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 09:08:16 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/?p=9</guid>
		<description><![CDATA[It&#8217;s that time of the year again. A new version of ubuntu is out and I had to update. I have had a not so good experience with upgrades so I decided to go for a fresh installation. I downloaded the 32bit standard cd from the ubuntu website, took a backup, formatted my feisty partition [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s that time of the year again. A new version of ubuntu is out and I had to update. I have had a not so good experience with upgrades so I decided to go for a fresh installation. I downloaded the 32bit standard cd from the <a href="http://www.ubuntu.com/getubuntu">ubuntu website</a>, took a backup, formatted my feisty partition and took the plunge.</p>
<p><span id="more-9"></span></p>
<p>I have an HP tx1003au laptop which is known to be slightly difficult to configure with linux. There is a huge <a href="http://ubuntuforums.org/showthread.php?t=442483">thread</a>(33 pages so far) on ubuntuforums.org specifically for this series of machines. I&#8217;ve been following this thread right since the beginning and I am posting the steps that I had to take. The information in this thread is a lot more than you need and it took me hours to go through it and get every piece of hardware going one by one.</p>
<h3>Booting from live CD</h3>
<p>As with recent ubuntu distributions gutsy comes with a live CD. I was not able to boot from the live CD directly. I had a similar problem with Feisty so I knew that I need to supply a certain set of kernel parameters to get my laptop to boot. The following parameters seem to work for me</p>
<pre>
quiet splash noapic irqpoll
</pre>
<p>If you are new to linux then follow the following steps.</p>
<p>Load the CD in your CD ROM and restart the computer. You will be shown a screen with options. Press F6 for &#8220;other options&#8221;. Now a line of text would be visible at the bottom of the screen. Type &#8220;noapic irqpoll&#8221; at the end of the line(before the &#8211;) and press enter.</p>
<h3>Installation</h3>
<p>Once I was able to boot from the live CD the installation went off smoothly. The only thing was that after installing the boot parameters were not automatically added to the boot configuration. So don&#8217;t restart your system straight away after installation. Edit the following file em>/boot/grub/menu.lst</em> and add the boot parameters string at the end of the line that looks something like this</p>
<pre>
kernel		/boot/vmlinuz-2.6.22-14-generic root=UUID=aa0998d4-b656-4ad4-854f-8fe9d950d17f quiet splash noapic irqpoll
</pre>
<h3>Wireless</h3>
<p>The first thing that I needed to configure was wireless networking. For this I used ndiswrapper. The instructions are given very nicely in this post.</p>
<p><a href="http://ubuntuforums.org/showpost.php?p=3491929&#038;postcount=257">http://ubuntuforums.org/showpost.php?p=3491929&#038;postcount=257</a></p>
<p>Note: I needed to install wine since I wasn&#8217;t able to extract the driver directly from the exe. For installing wine type this in a terminal window(applications -&gt; accessories -&gt; terminal)</p>
<pre>
sudo apt-get install wine
</pre>
<p>And after installing wine I double clicked on the driver file and installed it. Then I was able to locate the driver file by browsing the the following directory on my system<br />
<em>~/.wine/drive_c/SWSetup</em> (~ stands for home directory)</p>
<p>For connecting and disconecting to wireless networks you can use the networking application provided by default which can be accessed via system -&gt; administration -&gt; network. But I prefer to use the software wifi-radar which seems to work better in my case. For installing wifi radar type this in a terminal</p>
<pre>
sudo apt-get install wifi-radar
</pre>
<p>Note: You might need to enable some repositories for using the above software. For more information see this<br />
<a href="https://help.ubuntu.com/community/Repositories">https://help.ubuntu.com/community/Repositories</a></p>
<h3>Audio</h3>
<p>The audio didn&#8217;t work by default. To make it work I had to add the following line to the file <em>/etc/modprobe.d/alsa-base</em></p>
<pre>
options snd-hda-intel index=0 model=3stack position_fix=0 single_cmd=0
</pre>
<p><s>I had to restart after this. The audio now works but the front jacks are not recognized. I&#8217;ve read that the front jacks can be made to work by downloading and compiling the latest version of alsa drivers. I will try that at a later stage. For the moment I just wanted basic functionality running so that I could start using my system for some coding <img src='http://www.codepencil.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </s></p>
<p>Edit: The audio works perfectly after compiling and installing latest alsa drivers. Here are the instructions.</p>
<ol>
<li>Download the latest alsa drivers from here<br />
<a href="ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.15.tar.bz2">ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.15.tar.bz2</a>
</li>
<li>Untar the archive
<pre>
$ tar -xvf alsa-driver-1.0.15.tar.bz2
</pre>
</li>
<li>Compile and build the drivers
<pre>
$ cd alsa-driver-1.0.15/
$ ./configure
$ make
$ sudo make install
</pre>
<p>make should take a few minutes because it is compiling the source code.<br />
(in case you get a message that make cannot be found then you need to install the &#8220;build-essentials&#8221; package)
</li>
<li>Reboot your system</li>
</ol>
<p>Audio should be working now. In case it doesn&#8217;t try unmuting the controls in the volume mixer or increasing the volume.</p>
<h3>Things that work out of the box</h3>
<p>Not everything required tweaking and some of the things worked by default. Here&#8217;s what I was able to test.</p>
<ul>
<li>Hardware buttons (Sound volume buttons, DVD button and playback control buttons)</li>
<li>Memory card slot (tried Memory Stick Pro)</li>
<li>Infra-red remote</li>
<li>Microphones on the screen</li>
<li>Web cam (To use the webcam select the V4L2 as the video driver in your selected application. I tested this with Ekiga)</li>
</ul>
<h3>Display Drivers(NVidia)</h3>
<p>For installing the display drivers System -&gt; Administration -&gt; Restricted Drivers Manager. Click on the Nvidia accelerated graphics driver checkbox. The drivers should be installed automatically.</p>
<h3>Touchscreen</h3>
<p>This is the most tricky bit. With my previous installation I spent many days making this work. And I was hoping that this time it would take less time. <s>I still have to calibrate the touch screen and I will be able to do that later in the evening. In the meantime here are the steps that I followed to get it running and some notes that I had from last time. The basic steps are given in this post.<br />
<a href="http://ubuntuforums.org/showpost.php?p=2792971&#038;postcount=16">http://ubuntuforums.org/showpost.php?p=2792971&#038;postcount=16</a></s></p>
<p>Edit: The touchscreen works perfectly and is very easy to setup based on this post by waspbr on the ubuntu forums<br />
<a href="http://ubuntuforums.org/showpost.php?p=4197376&#038;postcount=542">http://ubuntuforums.org/showpost.php?p=4197376&#038;postcount=542</a></p>
<h3>External Display</h3>
<p>I tried connecting my laptop to a projector. The standard System -> Administration -> Screens and Graphics did not work for me. I then installed nvidia-settings.</p>
<pre>
sudo apt-get install nvidia-settings
</pre>
<p>After installing you can launch the application by typing &#8220;nvidia-settings&#8221; in the shell. This seems to work well at the moment and I was able to connect to an external display.</p>
<h3>Things I did not try</h3>
<ul>
<li>Getting the remaining buttons on the panel to work</li>
<li>Internal modem</li>
</ul>
<p>That&#8217;s it for the moment. Hope it helps save time for others with a similar setup.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/installing-ubuntu-gutsy-gibbon-on-my-hp-tx1003au-laptop/feed/</wfw:commentRss>
		<slash:comments>62</slash:comments>
		</item>
		<item>
		<title>Struts2 &#8211; Dojo Dynamic Tree</title>
		<link>http://www.codepencil.com/index.php/struts2-dojo-dynamic-tree/</link>
		<comments>http://www.codepencil.com/index.php/struts2-dojo-dynamic-tree/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 06:50:22 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[struts2]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/?p=7</guid>
		<description><![CDATA[In my previous attempt at creating a tree using struts2 and dojo, I stumbled upon a roadblock. As the size of the tree grew larger the performance started deteriorating. Our tree had 500 nodes and it took about 1min 20sec for the tree to render in internet explorer 6!
So the need was to create a [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="?p=4">previous attempt</a> at creating a tree using struts2 and dojo, I stumbled upon a roadblock. As the size of the tree grew larger the performance started deteriorating. Our tree had 500 nodes and it took about <strong>1min 20sec</strong> for the tree to render in internet explorer 6!</p>
<p>So the need was to create a dynamic tree which would load nodes as and when required.</p>
<p><span id="more-7"></span></p>
<p>I managed to create a simple application based on the struts-blank application which demonstrates how this can be achieved. I am pasting the code here so that it can help other people who want to achieve this using struts 2.0.9.</p>
<h3>The JSP Code</h3>
<p>I start by creating a <em>dynamicTree.jsp</em> file which will paint the tree. </p>
<p>I will create a tree with one root node in my html page and when that node is expanded its sub nodes will be loaded. It is possible to load a tree with any number of nodes in the beginning but I am going to keep this example simple so I am starting with a single node.</p>
<p>For painting the tree tag and the root node I <em>could not</em> use the struts2 taglib as I need to use attributes for dojo widgets that are not supported by struts2. Like the attribute <em>&#8216;controller&#8217;</em> is not supported by the tree tag and <em>&#8216;isFolder&#8217;</em> is not supported by the <em>treeNode</em> tag. The next version (2.1.0) has this fixed but the latest stable version at the moment is 2.0.9.</p>
<p>Here is what my jsp looks like</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>%@ page <span style="color: #000066;">contentType</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> %<span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>%@ taglib <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;s&quot;</span> <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;/struts-tags&quot;</span> %<span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;html<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;head<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;s:head</span> <span style="color: #000066;">theme</span>=<span style="color: #ff0000;">&quot;ajax&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
   //Load the tree controller and extensions
  dojo.require(&quot;dojo.widget.TreeLoadingController&quot;);
  dojo.require(&quot;dojo.widget.TreeControllerExtension&quot;);
&nbsp;
  dojo.addOnLoad(function() {
    //Add the extensions to the controller
    dojo.lang.mixin(dojo.widget.byId('treeController'), dojo.widget.TreeControllerExtension.prototype);
  });
&nbsp;
}
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/head<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;body<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">dojoType</span>=<span style="color: #ff0000;">&quot;TreeLoadingController&quot;</span>
  <span style="color: #000066;">widgetId</span>=<span style="color: #ff0000;">&quot;treeController&quot;</span>
  <span style="color: #000066;">RPCUrl</span>=<span style="color: #ff0000;">&quot;tree_gettreenodes.action&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;dojo:TreeSelector</span> <span style="color: #000066;">widgetId</span>=<span style="color: #ff0000;">&quot;treeSelector_contentTree&quot;</span>
  <span style="color: #000066;">eventNames</span>=<span style="color: #ff0000;">&quot;select:treeSelected;&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/dojo:TreeSelector<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">dojoType</span>=<span style="color: #ff0000;">&quot;Tree&quot;</span> 
  <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;contentTree&quot;</span> <span style="color: #000066;">selector</span>=<span style="color: #ff0000;">&quot;treeSelector_contentTree&quot;</span>
  <span style="color: #000066;">controller</span>=<span style="color: #ff0000;">&quot;treeController&quot;</span> <span style="color: #000066;">toggle</span>=<span style="color: #ff0000;">&quot;fade&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">dojoType</span>=<span style="color: #ff0000;">&quot;TreeNode&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;&lt;s:property value='#request.rootNode.name'/&gt;</span>&quot;
    id=&quot;<span style="color: #009900;">&lt;s:property value='#request.rootNode.id'/&gt;</span>&quot; isFolder=&quot;true&quot;&gt;<span style="color: #009900;">&lt;/div&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;/div&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;/body&gt;</span>
<span style="color: #009900;">&lt;/html&gt;</span></span></pre></div></div>

<h3>struts.xml</h3>
<p>My struts.xml is pretty simple. There is one mapping to an action class which will expose methods for painting the tree and a default result for loading the jsp.</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;struts<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;constant</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;struts.enable.DynamicMethodInvocation&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;constant</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;struts.devMode&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;package</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;default&quot;</span> <span style="color: #000066;">extends</span>=<span style="color: #ff0000;">&quot;struts-default&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
	<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;action</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;tree_*&quot;</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;{1}&quot;</span> 
            <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;com.codepencil.sandbox.tree.web.action.DynamicTreeAction&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
    	    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;result<span style="font-weight: bold; color: black;">&gt;</span></span></span>/tree/dynamicTree.jsp<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/result<span style="font-weight: bold; color: black;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/action<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/package<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/struts<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<h3>The Action Class</h3>
<p>In the action class I need to implement a method that will be called when child nodes of a tree are requested. When the request is made dojo passes a parameter name <em>data</em> which contains the JSON objects of the tree and the tree node that was clicked. The parameter looks something like this.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">&quot;node&quot;</span>:<span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">&quot;widgetId&quot;</span>:<span style="color: #3366CC;">&quot;1&quot;</span> isFolder=\<span style="color: #3366CC;">&quot;true&quot;</span>,<span style="color: #3366CC;">&quot;objectId&quot;</span>:<span style="color: #3366CC;">&quot;&quot;</span>,<span style="color: #3366CC;">&quot;index&quot;</span>:<span style="color: #CC0000;">1</span>,<span style="color: #3366CC;">&quot;isFolder&quot;</span>:<span style="color: #003366; font-weight: bold;">true</span><span style="color: #66cc66;">&#125;</span>, <span style="color: #3366CC;">&quot;tree&quot;</span>:<span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">&quot;widgetId&quot;</span>:<span style="color: #3366CC;">&quot;contentTree&quot;</span>,<span style="color: #3366CC;">&quot;objectId&quot;</span>:<span style="color: #3366CC;">&quot;&quot;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The treeLoadingController expects the server response to be a JSON array of <em>node</em> objects. For dealing with JSON I am using the set of Java classes available at <a href="http://www.json.org/java/">json.org</a> Since my needs are very basic I can make do with these simple classes. You can use any JSON library of your choice.</p>
<p>After this I write an action class and create a function named gettreenodes which does this job for me.</p>
<p>This is my action code.</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">package</span> com.<span style="color: #006600;">codepencil</span>.<span style="color: #006600;">sandbox</span>.<span style="color: #006600;">tree</span>.<span style="color: #006600;">web</span>.<span style="color: #006600;">action</span>;
&nbsp;
<span style="color: #a1a100;">import java.io.IOException;</span>
<span style="color: #a1a100;">import java.io.PrintWriter;</span>
<span style="color: #a1a100;">import java.util.List;</span>
<span style="color: #a1a100;">import javax.servlet.http.HttpServletRequest;</span>
<span style="color: #a1a100;">import javax.servlet.http.HttpServletResponse;</span>
<span style="color: #a1a100;">import org.apache.struts2.interceptor.ServletRequestAware;</span>
<span style="color: #a1a100;">import org.apache.struts2.interceptor.ServletResponseAware;</span>
<span style="color: #a1a100;">import org.apache.struts2.showcase.ajax.tree.Category;</span>
<span style="color: #a1a100;">import org.json.JSONException;</span>
<span style="color: #a1a100;">import org.json.JSONObject;</span>
<span style="color: #a1a100;">import org.json.JSONStringer;</span>
<span style="color: #a1a100;">import com.opensymphony.xwork2.ActionSupport;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DynamicTreeAction <span style="color: #000000; font-weight: bold;">extends</span> ActionSupport <span style="color: #000000; font-weight: bold;">implements</span> ServletResponseAware,ServletRequestAware <span style="color: #66cc66;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #993333;">long</span> serialVersionUID = -9131739831820245692L;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #aaaadd; font-weight: bold;">String</span> data;
    <span style="color: #000000; font-weight: bold;">private</span> HttpServletResponse response;
    <span style="color: #000000; font-weight: bold;">private</span> HttpServletRequest request;
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #aaaadd; font-weight: bold;">String</span> getData<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> data;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #993333;">void</span> setData<span style="color: #66cc66;">&#40;</span><span style="color: #aaaadd; font-weight: bold;">String</span> data<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006600;">data</span> = data;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #993333;">void</span> setServletResponse<span style="color: #66cc66;">&#40;</span>HttpServletResponse response<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006600;">response</span> = response;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #993333;">void</span> setServletRequest<span style="color: #66cc66;">&#40;</span>HttpServletRequest request<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006600;">request</span> = request;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #aaaadd; font-weight: bold;">String</span> gettree<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        Category rootNode = Category.<span style="color: #006600;">getById</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
        request.<span style="color: #006600;">setAttribute</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;rootNode&quot;</span>, rootNode<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #000000; font-weight: bold;">return</span> SUCCESS;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #aaaadd; font-weight: bold;">String</span> gettreenodes<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        JSONObject jsonData,node;
        <span style="color: #aaaadd; font-weight: bold;">PrintWriter</span> writer;
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #66cc66;">&#123;</span>
            jsonData = <span style="color: #000000; font-weight: bold;">new</span> JSONObject<span style="color: #66cc66;">&#40;</span>data<span style="color: #66cc66;">&#41;</span>;
            node = jsonData.<span style="color: #006600;">getJSONObject</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;node&quot;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #aaaadd; font-weight: bold;">String</span> nodeId = node.<span style="color: #006600;">get</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;widgetId&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">toString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            Category category = Category.<span style="color: #006600;">getById</span><span style="color: #66cc66;">&#40;</span><span style="color: #aaaadd; font-weight: bold;">Long</span>.<span style="color: #006600;">parseLong</span><span style="color: #66cc66;">&#40;</span>nodeId<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
            JSONStringer stringer = <span style="color: #000000; font-weight: bold;">new</span> JSONStringer<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            stringer.<span style="color: #006600;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            List&lt;Category&gt; children = category.<span style="color: #006600;">getChildren</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;  
            <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> i=<span style="color: #cc66cc;">0</span>;i&lt;children.<span style="color: #006600;">size</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;i++<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
                Category childCategory = children.<span style="color: #006600;">get</span><span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">object</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">key</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;id&quot;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">value</span><span style="color: #66cc66;">&#40;</span>childCategory.<span style="color: #006600;">getId</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">key</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;title&quot;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">value</span><span style="color: #66cc66;">&#40;</span>childCategory.<span style="color: #006600;">getName</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">key</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;isFolder&quot;</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">value</span><span style="color: #66cc66;">&#40;</span>childCategory.<span style="color: #006600;">getChildren</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">size</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>&gt;<span style="color: #cc66cc;">0</span> ? <span style="color: #000000; font-weight: bold;">true</span> : <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
                stringer.<span style="color: #006600;">endObject</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
            stringer.<span style="color: #006600;">endArray</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            writer = response.<span style="color: #006600;">getWriter</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            writer.<span style="color: #006600;">write</span><span style="color: #66cc66;">&#40;</span>stringer.<span style="color: #006600;">toString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #66cc66;">&#40;</span>JSONException e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            e.<span style="color: #006600;">printStackTrace</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #66cc66;">&#40;</span><span style="color: #aaaadd; font-weight: bold;">IOException</span> e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            e.<span style="color: #006600;">printStackTrace</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">null</span>;
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>For creating the tree I am using the Category class from the struts showcase application as I was feeling too lazy to write a brand new class for this purpose. In my actual application I have some complex hibernate mappings and I load the tree node objects from the database.</p>
<p>Another important thing that caused me a lot of frustration is that you should always return <strong>null</strong> from an action method that handles ajax calls otherwise you wont get the desired result.</p>
<h3>The Sample Application</h3>
<p>The code of the full application can be downloaded from the following link. You can simply deploy this as it is in a container. (I have tested it with Tomcat5.5 and jdk6)</p>
<p><a href="/code/struts2-dynamic-tree-application.zip">Download the Dynamic Tree Sample Application</a></p>
<p>You can use the tree loading controller for saving and restoring the state of the tree in a similar way as in the <a href="?p=4">previous example</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/struts2-dojo-dynamic-tree/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Creating A Tree Widget Using Struts2</title>
		<link>http://www.codepencil.com/index.php/creating-a-tree-widget-using-struts2/</link>
		<comments>http://www.codepencil.com/index.php/creating-a-tree-widget-using-struts2/#comments</comments>
		<pubDate>Wed, 12 Sep 2007 08:45:23 +0000</pubDate>
		<dc:creator>Manu Mahajan</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[struts2]]></category>

		<guid isPermaLink="false">http://www.codepencil.com/?p=4</guid>
		<description><![CDATA[Struts 2 includes the dojo toolkit and provides a taglib for using dojo features in a java environment. The &#60;s:tree&#62; tag can be used to generate a tree widget which can be very useful for displaying hierarchical data. For example, I recently used it in a project to display the folder structure for a filesystem.
This [...]]]></description>
			<content:encoded><![CDATA[<p>Struts 2 includes the dojo toolkit and provides a taglib for using dojo features in a java environment. The &lt;s:tree&gt; tag can be used to generate a tree widget which can be very useful for displaying hierarchical data. For example, I recently used it in a project to display the folder structure for a filesystem.</p>
<p>This is a screenshot of what the rendered tree looks like.</p>
<p><img width="256" src="http://www.codepencil.com/attachments/struts2-tree.gif" alt="The tree widget" height="251" style="width: 256px; height: 251px" title="The tree widget" /></p>
<p>Our final tree will contain the following features</p>
<ul>
<li>Ability to set a default selected node</li>
<li>Trapping node select events</li>
<li>Trapping expand/collapse events</li>
<li>Saving/restoring the state of the tree</li>
</ul>
<p><span id="more-4"></span></p>
<p>If you are of the impatient type and want a quick solution you can jump to the <a href="#summary">summary with working code.</a></p>
<p>Struts2 contains the showcase web application which provides some sample code. It can be downloaded from <a href="http://struts.apache.org/download.cgi#struts209" title="Struts2 downloads">struts2 downloads</a> page. (Download the <em>sample applications</em> package).</p>
<p>Unfortunately, some features in the tree example are broken as of now. We can use the tree example as a reference and build upon it to add more features.</p>
<p>I am discussing the presentation logic in the jsp. If you want to understand how the data structure to be displayed is created have a look at the following class in the showcase application.</p>
<p>org.apache.struts2.showcase.ajax.tree.Category</p>
<h3>Displaying the tree</h3>
<p>To begin with our jsp must contain the &lt;s:head&gt; tag inside the &lt;head&gt; section. This tag tells struts to paint the initialization code for dojo.</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;s:head</span> <span style="color: #000066;">theme</span>=<span style="color: #ff0000;">&quot;ajax&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span></pre></div></div>

<p>To paint the tree we use the &lt;s:tree&gt; tag</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;float:left; margin-right: 50px;&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;s:tree</span> 
    <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;contentTree&quot;</span> 
    <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;contentTree&quot;</span>
    <span style="color: #000066;">theme</span>=<span style="color: #ff0000;">&quot;ajax&quot;</span>
    <span style="color: #000066;">rootNode</span>=<span style="color: #ff0000;">&quot;%{rootNode}&quot;</span> 
    <span style="color: #000066;">childCollectionProperty</span>=<span style="color: #ff0000;">&quot;children&quot;</span> 
    <span style="color: #000066;">nodeIdProperty</span>=<span style="color: #ff0000;">&quot;id&quot;</span>
    <span style="color: #000066;">nodeTitleProperty</span>=<span style="color: #ff0000;">&quot;name&quot;</span>
    <span style="color: #000066;">treeSelectedTopic</span>=<span style="color: #ff0000;">&quot;treeSelected&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/s:tree<span style="font-weight: bold; color: black;">&gt;</span></span></span> 
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<p>The &#8220;rootNode&#8221; attribute defines the data structure(Collection object) that will be displayed in the form of a tree. This needs to be set via an action. In the showcase example the ShowDynamicTreeAction.java is doing this job for us.</p>
<p><a name="capture-node-select"></a></p>
<h3>Capturing node select events</h3>
<p>In the &lt;s:tree&gt; tag above the &#8220;treeSelectedTopic&#8221; defines the dojo event topic that will be published when a node of the tree is selected by the user. </p>
<p>This however, does not work by default in struts 2.0.9. A jira ticket has been lodged for this <a href="https://issues.apache.org/struts/browse/WW-1813" target="_blank">https://issues.apache.org/struts/browse/WW-1813</a> and it will be fixed in version 2.1.0</p>
<p>To work around this for the current version download the updated version of the file <a href="http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/tree.ftl?view=markup&#038;pathrev=528866" target="_blank">tree.ftl</a> from the SVN and place it in your WEB_APPLICATION_ROOT/templates/ajax directory </p>
<p>For trapping node select events make a javascript funtion that would be called when the event fires and connect it to the event by using dojo.topic.subscribe as follows.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> treeNodeSelected<span style="color: #66cc66;">&#40;</span>message<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">/*
  * Place your logic here
  * I am just displaying the id of the node that was clicked
  */</span>
             <span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>message.<span style="color: #006600;">node</span>.<span style="color: #006600;">widgetId</span><span style="color: #66cc66;">&#41;</span>;
     <span style="color: #66cc66;">&#125;</span>;
dojo.<span style="color: #006600;">event</span>.<span style="color: #006600;">topic</span>.<span style="color: #006600;">subscribe</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;treeSelected&quot;</span>,<span style="color: #000066; font-weight: bold;">this</span>,treeNodeSelected<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<h3>Trapping expand/collapse events</h3>
<p>The TreeLoadingController widget is required for being able to capture expand and collapse events. We will also be using the tree controller extensions which will give us additional ability to control the loading of the tree.</p>
<p>First, tell dojo to load the required files</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #009900; font-style: italic;">//Load the tree controller widget and controller extension</span>
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;dojo.widget.TreeLoadingController&quot;</span><span style="color: #66cc66;">&#41;</span>;
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;dojo.widget.TreeControllerExtension&quot;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #009900; font-style: italic;">// Add extensions to controller.</span>
dojo.<span style="color: #006600;">lang</span>.<span style="color: #006600;">mixin</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'treeController'</span><span style="color: #66cc66;">&#41;</span>, dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">TreeControllerExtension</span>.<span style="color: #006600;">prototype</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Also, add the tree controller widget to the body section of your page</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">dojoType</span>=<span style="color: #ff0000;">&quot;TreeLoadingController&quot;</span> <span style="color: #000066;">widgetId</span>=<span style="color: #ff0000;">&quot;treeController&quot;</span> <span style="color: #000066;">RPCUrl</span>=<span style="color: #ff0000;">&quot;local&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<p>Now subscribe to the expand and collapse events</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">dojo.<span style="color: #006600;">event</span>.<span style="color: #006600;">topic</span>.<span style="color: #006600;">subscribe</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;contentTree/expand&quot;</span>,saveExpandedIndices<span style="color: #66cc66;">&#41;</span>;
dojo.<span style="color: #006600;">event</span>.<span style="color: #006600;">topic</span>.<span style="color: #006600;">subscribe</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;contentTree/collapse&quot;</span>,saveExpandedIndices<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>&#8220;saveExpandedIndices&#8221; is the name of the function that I am going to use to save the state of the tree every time a node is expanded/collapsed. You can have your own function in its place if you want.</p>
<h3>Saving the state of the tree</h3>
<p>For saving the state of the tree. The treeController widget provides a function called &#8220;saveExpandedIndices&#8221; which returns a multi dimension array of integers, each integer representing an expanded node. You can save this array based on your logic. For my implementation I am storing it inside a cookie. For converting the object to a string I use json.js which you can get from <a href='http://www.json.org/json.js'>json.org</a></p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> saveExpandedIndices<span style="color: #66cc66;">&#40;</span>message<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  indices = dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'treeController'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">saveExpandedIndices</span><span style="color: #66cc66;">&#40;</span>
    dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'contentTree'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>readCookie<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;categoryTreeState&quot;</span><span style="color: #66cc66;">&#41;</span>==<span style="color: #003366; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span>
    createCookie<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;categoryTreeState&quot;</span>,indices.<span style="color: #006600;">toJSONString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">else</span> 
    updateCookie<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;categoryTreeState&quot;</span>,indices.<span style="color: #006600;">toJSONString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>We can load the same state of the tree anytime. I use it at the body onload event so that when the user revisits that page it is in the same state.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> restoreExpandedIndices<span style="color: #66cc66;">&#40;</span>indices<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'treeController'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">restoreExpandedIndices</span><span style="color: #66cc66;">&#40;</span>
    dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'contentTree'</span><span style="color: #66cc66;">&#41;</span>, indices
  <span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> bodyOnLoad<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  treeState = readCookie<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;categoryTreeState&quot;</span><span style="color: #66cc66;">&#41;</span>;
  indices = treeState.<span style="color: #006600;">parseJSON</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  restoreExpandedIndices<span style="color: #66cc66;">&#40;</span>indices<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>Setting the default selected element</h3>
<p>Sometime you might want to select a node of the tree on page load or at any other event. This can be accomplished by the following code.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">treeSelector = dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'treeSelector_contentTree'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #009900; font-style: italic;">//The id will be treeSelector_TREENAME (its defined in tree.ftl)</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900; font-style: italic;">// try to select node based on ID</span>
<span style="color: #66cc66;">&#123;</span>
  treeNode = dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span>ID<span style="color: #66cc66;">&#41;</span> 
  treeSelector.<span style="color: #006600;">doSelect</span><span style="color: #66cc66;">&#40;</span>treeNode<span style="color: #66cc66;">&#41;</span>;
  <span style="color: #009900; font-style: italic;">//publish treeSelected topic to trigger handling of event</span>
  dojo.<span style="color: #006600;">event</span>.<span style="color: #006600;">topic</span>.<span style="color: #006600;">publish</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;treeSelected&quot;</span>, <span style="color: #66cc66;">&#123;</span>node: dojo.<span style="color: #006600;">widget</span>.<span style="color: #006600;">byId</span><span style="color: #66cc66;">&#40;</span>treeSelection<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; 
<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066; font-weight: bold;">catch</span> <span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span><span style="color: #009900; font-style: italic;">// if unable to select or node not found</span>
<span style="color: #66cc66;">&#123;</span>
  treeNode = tree.<span style="color: #006600;">getDescendants</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span> <span style="color: #009900; font-style: italic;">// try selecting the root node</span>
  treeSelector.<span style="color: #006600;">doSelect</span><span style="color: #66cc66;">&#40;</span>treeNode<span style="color: #66cc66;">&#41;</span>;
  dojo.<span style="color: #006600;">event</span>.<span style="color: #006600;">topic</span>.<span style="color: #006600;">publish</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;treeSelected&quot;</span>, <span style="color: #66cc66;">&#123;</span>node: tree.<span style="color: #006600;">getDescendants</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>Summarizing</h3>
<p><a name="summary"></a></p>
<p>Here is a summary of the code snippets put together which you can directly use in your application.</p>

<div class="wp_syntax"><div class="code"><pre class="xml">&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;html<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;head<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;s:head</span> <span style="color: #000066;">theme</span>=<span style="color: #ff0000;">&quot;ajax&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;script</span> <span style="color: #000066;">language</span>=<span style="color: #ff0000;">&quot;Javascript&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;/scripts/json.js&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;script</span> <span style="color: #000066;">language</span>=<span style="color: #ff0000;">&quot;Javascript&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;/scripts/cookies.js&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;script</span> <span style="color: #000066;">language</span>=<span style="color: #ff0000;">&quot;javascript&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
&nbsp;
  //The following extensions are required to save or restore state of a tree
  dojo.require(&quot;dojo.widget.TreeLoadingController&quot;);
  dojo.require(&quot;dojo.widget.TreeControllerExtension&quot;);
&nbsp;
  //This function is called after dojo scripts are loaded
  dojo.addOnLoad(function() {
    dojo.lang.mixin(dojo.widget.byId('treeController'), dojo.widget.TreeControllerExtension.prototype);
    //The following code will make sure that the saveExpandedIndices function is called everytime a node is collapsed or expanded
    dojo.event.topic.subscribe(&quot;contentTree/expand&quot;,saveExpandedIndices);
    dojo.event.topic.subscribe(&quot;contentTree/collapse&quot;,saveExpandedIndices);
  });
&nbsp;
  //The following function saves the state of the tree
  function saveExpandedIndices(message) {
    indices = dojo.widget.byId('treeController').saveExpandedIndices(
    dojo.widget.byId('contentTree')
  );
  if (readCookie(&quot;categoryTreeState&quot;)==null)
    createCookie(&quot;categoryTreeState&quot;,indices.toJSONString());
  else 
    updateCookie(&quot;categoryTreeState&quot;,indices.toJSONString());
  }
&nbsp;
  //The following function restores the state of the tree. This can probably be called body-onload
  //You will have to pass it the stored indices object though
  function restoreExpandedIndices(indices) {
    dojo.widget.byId('treeController').restoreExpandedIndices(
    dojo.widget.byId('contentTree'), indices
    );
  }
function bodyOnLoad(){
  treeState = readCookie(&quot;categoryTreeState&quot;);
  indices = treeState.parseJSON();
  restoreExpandedIndices(indices);
}
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/head<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;body</span> <span style="color: #000066;">onload</span>=<span style="color: #ff0000;">&quot;bodyOnLoad()&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">dojoType</span>=<span style="color: #ff0000;">&quot;TreeLoadingController&quot;</span> <span style="color: #000066;">widgetId</span>=<span style="color: #ff0000;">&quot;treeController&quot;</span> <span style="color: #000066;">RPCUrl</span>=<span style="color: #ff0000;">&quot;local&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;s:tree</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;contentTree&quot;</span> 
    <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;contentTree&quot;</span>
    theme = <span style="color: #ff0000;">&quot;ajax&quot;</span>
    <span style="color: #000066;">rootNode</span>=<span style="color: #ff0000;">&quot;%{rootNode}&quot;</span>
    <span style="color: #000066;">childCollectionProperty</span>=<span style="color: #ff0000;">&quot;children&quot;</span>
    <span style="color: #000066;">nodeIdProperty</span>=<span style="color: #ff0000;">&quot;id&quot;</span>
    <span style="color: #000066;">nodeTitleProperty</span>=<span style="color: #ff0000;">&quot;name&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/s:tree<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/body<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<p><del datetime="2007-09-19T10:43:31+00:00">I am working on a tree with lazy loading that will load partially at first and the rest will be loaded based on when the user expands a node. I will post the code when I get it working!</del></p>
<hr />
<h4>Follow Ups:</h4>
<p>&bull; <a href="/?p=7">Struts2 &#8211; Dojo Dynamic Tree</a> : In this example I have attempted to create a tree which loads partially at first and rest is loaded as and when requested by the user.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepencil.com/index.php/creating-a-tree-widget-using-struts2/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
