HOW-TO: Integrate a YUI tree with Rails
July 16th, 2006
acomplia online cialis cost cialis online pharmacy viagra for order cheapest accutane cheap cialis viagra uk purchase viagra online where to order cialis purchase viagra no rx cheap price cialis accutane sale find discount cialis find discount viagra online generic cialis cheap cialis in uk buy cialis from canada acomplia online stores viagra for sale lowest price for cialis buy viagra on line price of viagra drug viagra online purchase 25mg viagra viagra cost viagra cheap price purchase cialis online buy viagra lowest price pharmacy viagra best price for viagra purchase accutane cialis pills tablet viagra cheap acomplia online order viagra overnight delivery buy cialis overnight delivery viagra in bangkok cialis bangkok purchase cialis no rx cheap cialis no rx purchase acomplia online cheap generic cialis cheapest cialis viagra in us cialis in bangkok order viagra online best price viagra viagra malaysia where to buy acomplia cheapest cialis prices cialis cheap buying cialis order generic viagra viagra order buying generic viagra no prescription cialis buy accutane buy viagra no rx buy cheapest viagra buy acomplia cheap order viagra no prescription required buy viagra in us 20mg cialis order viagra in us acomplia cheap buying viagra viagra cheap buy cheap viagra online fda approved viagra cialis information cost of viagra find cheap cialis cialis from canada purchase viagra overnight delivery acomplia discount fda approved cialis viagra rx find no rx cialis viagra discount certified cialis cialis without a prescription accutane acomplia pharmacy cialis overnight shipping viagra australia sale cialis buy sildenafil citrate buy cialis from us online viagra cialis soft acomplia prices buy discount cialis viagra pill viagra prices buy viagra overnight delivery online cialis order cialis cheap online discount viagra overnight delivery viagra online without prescription compare viagra prices online cheapest generic cialis accutane online overnight cialis cheap cialis without prescription buy sildenafil in uk viagra no rx cialis cheap price 50mg viagra buy accutane online erectile dysfunction cheap viagra overnight delivery cheap cialis tablets viagra pharmacy online acomplia without a prescription cheap accutane tablets buy cialis without prescription lowest price acomplia cialis tablet buy generic accutane find cialis without prescription order accutane cheap cialis overnight delivery cialis price cialis from india cialis no rx buy discount cialis online cialis overnight buy acomplia without prescription cialis tablets cheap viagra in usa buy viagra in canada cialis pharmacy online order cialis in us discount cialis 20 mg cialis acomplia online cheap cheapest viagra online cialis prescription order cialis on internet buy sildenafil in spain buy generic cialis cheap cialis in canada viagra tablets accutane without prescription cialis canada buy cheap acomplia online cheap viagra cheap cialis pharmacy find cialis on internet acomplia prescription buy cialis cheap order cheap cialis online find cialis no prescription required viagra overnight delivery buy viagra low price compare cialis prices 25 mg viagra order viagra no rx viagra online buy cialis no rx impotence treatment impotence cure viagra overnight online pharmacy cialis viagra online cheap find cialis online generic cialis online no rx cialis accutane generic cheapest acomplia prices buy viagra online cheap buy viagra internet acomplia no prescription pfizer viagra drug cialis online purchase order discount cialis cialis 10mg best price for cialis cheap viagra from usa find discount viagra cialis pill order viagra without prescription viagra generic purchase viagra without prescription buy acomplia online accutane cheap order viagra from canada cialis online without prescription cheap accutane cialis side effects cialis for sale buy cheap accutane online cialis generic discount cialis without prescription buy viagra from canada buy cialis internet discount viagra no rx viagra without a prescription drug cialis cialis pharmacy buy cialis generic cialis prices discount accutane order cialis no prescription impotence drugs cost viagra acomplia generic buy viagra online impotence medication order cialis from canada buy discount viagra acomplia acomplia pills purchase accutane online pharmacy online buy sildenafil internet buy accutane cheap viagra canada discount cialis online order cialis overnight delivery where to buy viagra cheap accutane online find no rx viagra cheap cialis from uk lowest price for viagra cheap viagra from canada approved cialis pharmacy 10 mg cialis viagra in uk cialis vs viagra cialis internet cheapest viagra prices accutane prescription buy cialis in us low cost cialis cialis buy online pharmacy cialis buying generic cialis purchase cialis overnight delivery buy discount viagra online order no rx viagra acomplia without prescription viagra buy order viagra from us viagra internet find discount cialis online acomplia for sale purchase cialis without prescription cialis drug discount viagra accutane prices buy sildenafil canada viagra in malaysia accutane online stores generic drugs buy viagra generic cialis purchase cialis us viagra medication price of accutane cheap cialis pill viagra no prescription find viagra buy cialis online cheap cheap cialis from canada cheap generic viagra price of cialis sale viagra viagra free sample order viagra order acomplia online where to order viagra viagra approved cialis for order buy sildenafil cheap buy accutane without prescription discount viagra without prescription cheap cialis from usa buy viagra no prescription required cialis discount cheap viagra on internet order generic cialis buying cialis online accutane without a prescription buy cialis lowest price viagra no rx required buy generic viagra online purchase cialis viagra buy drug order cialis without prescription viagra us 10mg cialis cheap acomplia tablets buy sildenafil in canada find viagra without prescription cialis overnight delivery buy viagra cheap cialis cheapest price cialis sale lowest price cialis cheapest generic viagra viagra soft tab no rx viagra cheap cialis no prescription purchase viagra viagra sale viagra india find viagra no prescription required impotence pills cialis 20mg 100 mg viagra buy cheap accutane buy cialis low price compare viagra prices cheapest viagra price impotence cheap viagra tablet tablet cialis order discount viagra viagra overnight shipping order viagra on internet buy cheap cialis online cost cialis buy sildenafil low cost order cialis no rx cheap viagra in uk cialis medication generic viagra cheap buy sildenafil online buy cheapest cialis on line order cialis no prescription required viagra drug buy viagra without prescription buy cialis on internet viagra cheap drug cheap viagra no prescription cheap viagra in canada cheap generic acomplia cheap viagra internet viagra pills cheap cialis in uk order cheap viagra online buy cialis from india cheap viagra no rx cheapest generic viagra online lowest price viagra cheap cialis in usa viagra sales order accutane online buy and purchase sildenafil online online pharmacy viagra viagra in australia certified viagra cialis malaysia viagra cheapest price cialis no rx required buy cheap acomplia buy sildenafil online without a prescription discount viagra online no prescription viagra viagra tablet viagra from india viagra cheap cialis internet order cialis 50 mg viagra buy cialis in canada order discount cialis online cialis no online prescription approved viagra pharmacy cialis soft tab cialis no prescription buy cialis order cheap cialis 100mg viagra order cialis online compare cialis prices online cheap viagra tablets cheap price viagra cialis cheap viagra online find viagra on internet cialis 20 mg viagra side effects cheap acomplia cialis without rx cialis without prescription cialis 10 mg viagra bangkok purchase acomplia cialis free delivery cheapest viagra buy viagra cialis india viagra vendors low cost viagra order viagra cheap online cheap viagra from uk generic accutane cheapest accutane prices viagra vs cialis generic acomplia accutane pills buy generic viagra generic viagra online generic viagra accutane discount find viagra online find cialis accutane pharmacy viagra online stores cialis buy order viagra in canada cialis online cheap viagra soft find cheap cialis online cheap viagra without prescription order viagra no prescription buy cheapest cialis order cialis in canada cheapest sildenafil citrate cialis uk cialis free sample cialis online review buy generic acomplia price of acomplia drug viagra generic cialis viagra no online prescription free viagra viagra information buy viagra from us buy viagra on internet cheapest acomplia order acomplia viagra buy online viagra online review where to buy cialis buy cheapest viagra online viagra without rx cialis approved viagra pharmacy order cheap viagra buy cialis online discount cialis no rx cheap viagra pill buy generic cialis online cialis online buy no rx viagra viagra online pharmacy cialis online stores buy cheap cialis buy cheapest cialis online buy cheap viagra accutane for sale cialis in australia buy cheap cialis internet acomplia sale buy viagra us overnight viagra lowest price accutane online accutane online acomplia find cheap viagra online best price cialis buy cheap viagra internet viagra free delivery cheap cialis on internet buy viagra from india cialis rx buying viagra online cheap generic accutane find cheap viagra where to buy accutane cialis australia cheapest cialis online order no rx cialis viagra purchase cialis vendors discount acomplia cialis cheap drug discount cialis overnight delivery cialis sales cialis buy drug cheapest generic cialis online buy cheapest viagra on line cheap cialis online cheap viagra pharmacy accutane online cheap buy acomplia viagra without prescription cheap cialis tablet cheapest cialis price buy no rx cialis cialis in us buy cialis on line free cialis order cialis from us cialis in malaysia accutane no prescription order discount viagra online cost of cialis buy cialis us cialis order viagra from canada viagra prescription buy cialis no prescription required viagra priceIn this episode of “Getting the Yahoo Interface Library to play with Rails” we will focus on trees. If you haven’t gone through it already, I suggest you at least give the first article in the series a glance. That article will give you a quick overview of how to dowload the YUI and configure a Rails project to make use of it. In this article, we will build a simple tree and, in the process, build a helper class that you can use in your projects to simplify the view code. Another useful reference is Yahoo’s reference page for the tree API.
When you are done with this tutorial, you will build a simple tree that you can invoke with: http://0.0.0.0:3000/tree/display

Configure your Rails Project for Yahoo Trees
Start by creating your YuiExample Rails project. Once that is created (or if you have already created it from the last example), create a controller called “tree”.
As before, you will need to copy some files from the yahoo directory structure into a Rails friendly one (NOTE: These instructions assume you have named your project YuiSample).
- Copy treeview.js: Copy treeview.js from
/yui/build/treeviewto/YuiSample/public/javascript/yui - Copy trees.css: Copy trees.js from
/yui/build/treeview/assetsto/YuiSample/public/stylesheets/yui - Copy tree imgates: Copy all the image files from
/yui/build/treeview/assetsto/YuiSample/public/images/yui/tree
At this point you have all the YUI files you need, but trees.css containts the wrong image URLs. Replace trees.css with this one:
/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
/* first or middle sibling, no children */
.ygtvtn {
width:16px; height:22px;
background: url(/images/yui/tree/tn.gif) 0 0 no-repeat;
}
/* first or middle sibling, collapsable */
.ygtvtm {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/tm.gif) 0 0 no-repeat;
}
/* first or middle sibling, collapsable, hover */
.ygtvtmh {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/tmh.gif) 0 0 no-repeat;
}
/* first or middle sibling, expandable */
.ygtvtp {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/tp.gif) 0 0 no-repeat;
}
/* first or middle sibling, expandable, hover */
.ygtvtph {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/tph.gif) 0 0 no-repeat;
}
/* last sibling, no children */
.ygtvln {
width:16px; height:22px;
background: url(/images/yui/tree/ln.gif) 0 0 no-repeat;
}
/* Last sibling, collapsable */
.ygtvlm {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/lm.gif) 0 0 no-repeat;
}
/* Last sibling, collapsable, hover */
.ygtvlmh {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/lmh.gif) 0 0 no-repeat;
}
/* Last sibling, expandable */
.ygtvlp {
width:16px; height:22px;
cursor:pointer ;
background: url(/images/yui/tree/lp.gif) 0 0 no-repeat;
}
/* Last sibling, expandable, hover */
.ygtvlph {
width:16px; height:22px; cursor:pointer ;
background: url(/images/yui/tree/lph.gif) 0 0 no-repeat;
}
/* Loading icon */
.ygtvloading {
width:16px; height:22px;
background: url(/images/yui/tree/loading.gif) 0 0 no-repeat;
}
/* the style for the empty cells that are used for rendering the depth
* of the node */
.ygtvdepthcell {
width:16px; height:22px;
background: url(/images/yui/tree/vline.gif) 0 0 no-repeat;
}
.ygtvblankdepthcell { width:16px; height:22px; }
/* the style of the div around each node */
.ygtvitem { }
/* the style of the div around each node's collection of children */
.ygtvchildren { }
* html .ygtvchildren { height:2%; }
/* the style of the text label in ygTextNode */
.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover {
margin-left:2px;
text-decoration: none;
}
.ygtvspacer { height: 10px; width: 10px; margin: 2px; }
Examing a simple YUI tree
The first thing to try is creating a simple hard-coded tree. Create a new RHTM file in YuiSample/app/views/tree called display.rhtml and paste the following code in it:
<html>
<head>
<title>YUI Tester: <%= controller.action_name %></title>
<%= javascript_include_tag "yui/yahoo",
"yui/dom",
"yui/event",
"yui/connection",
"yui/dragdrop",
"yui/treeview"%>
<%= stylesheet_link_tag 'yui/tree'%>
<%= stylesheet_link_tag 'appstylesheet'%>
</head>
<body>
<div id="mytree"></div>
<script type="text/javascript">
//<![CDATA[
function mytree_Init() {
var tree = new YAHOO.widget.TreeView("mytree");
var parent1 = new YAHOO.widget.TextNode({ label: "Cat 1", href:"http://www.yahoo.com" }, tree.getRoot(), false);
new YAHOO.widget.TextNode({ label: "Cat 1.1", href:"http://www.yahoo.com" }, parent1, false);
var parent1_2 = new YAHOO.widget.TextNode({ label: "Cat 1.2", href:"http://www.yahoo.com" }, parent1, false);
new YAHOO.widget.TextNode({ label: "Cat 1.2.1", href:"http://www.yahoo.com" }, parent1_2, false);
new YAHOO.widget.TextNode({ label: "Cat 1.2.2", href:"http://www.yahoo.com" }, parent1_2, false);
new YAHOO.widget.TextNode({ label: "Cat 1.3", href:"http://www.yahoo.com" }, parent1, false);
new YAHOO.widget.TextNode({ label: "Cat 2", href:"http://www.yahoo.com" }, tree.getRoot(), false);
tree.draw();
}
YAHOO.util.Event.addListener(window, "load", mytree_Init);
//]]>
</script>
</body>
</html>
There are three sections of this RHTML file.
- The header section simply imports the YUI javascript and stylesheets we need.
- The next section is really just one line:
<div id="mytree"></div>. This section defines the div object that the YUI API will use to build the tree object. - The last section is in the CDATA block we define. That is the javascript that defines and draws the tree. I don’t know if this is a hard requirement, but unlike the dialog objects, I had to define the javascript AFTER I defined the div tag in order for the functions to work.
In this particular example I am making use of the href property so each tree node is a clickable reference. By default, clicking on the node expands and collapses it. Refer to the Yahoo User Interface library link I provided above to see the various options for the TextNode constructor.
Designing a Rails friendly tree rendering algorithm
So the prior exampe was useful for understanding how the YUI API builds tree, but it is not really all that great for dynamic content generation using RoR. To solve this, I quickly put together an algorithm whose javascript and supporting datastructures will be easy to generate. This is done by first creating a datastructure that represents the pre-order traversal of the tree and then passing that datastructure into a general purpose javascript function that generates the tree using the YUI API.
The datastructure will be of the following form:
tree_data = [node_level_num, {yui tree node object def},...]
So, for example:
var test_data =
[0, { label: "Cat 1", href:"http://www.yahoo.com" },
1, { label: "Cat 1.1", href:"http://www.yahoo.com" },
1, { label: "Cat 1.2", href:"http://www.yahoo.com" },
2, { label: "Cat 1.2.1", href:"http://www.yahoo.com" },
2, { label: "Cat 1.2.2", href:"http://www.yahoo.com" },
1, { label: "Cat 1.3", href:"http://www.yahoo.com" },
0, { label: "Cat 2", href:"http://www.yahoo.com" }];
In the above example, the datastructure shows that:
- Categores 1 and 2 are level 0 in the tree, Categores 1.1, 1.2, and 1.3 are level 1 in the tree, and Categories 1.2.1, 1.2.2 are level 2 in the tree.
- Since this is a pre-order listing of the tree, it shows that Category 1 is the parent of Categories 1.1, 1.2, and 1.3
- …and that Category 1.2 is the parent of categores 1.2.1 and 1.2.2.
Now all we need is some code that takes this datastructure as input and generates the YUI tree:
function addChildrenNodes(currLevel, nodeIndex, parent) {
var lastNode;
var level = currLevel;
while (nodeIndex < test_data.length) {
var level = test_data[nodeIndex];
if (level == currLevel) {
nodeIndex++;
lastNode = new YAHOO.widget.TextNode(test_data[nodeIndex++], parent, false);
} else if (level < currLevel) {
return nodeIndex;
} else {
nodeIndex = addChildrenNodes(level, nodeIndex, lastNode);
}
}
return nodeIndex;
}
function mytree_Init() {
var tree = new YAHOO.widget.TreeView("mytree");
addChildrenNodes(0, 0, tree.getRoot());
tree.draw();
}
YAHOO.util.Event.addListener(window, "load", mytree_Init);
The workhorse function is addChildrenNodes. It is a recursive algorithm that iterates as long as there is data available and for each iteration, checks the level of the next set of data and does the following:
- The next node is at the current level: If the next node is at the current level, grab the level and the next node and advance the index through the node data. Create a YUI tree node and add it to the parent.
- The next node is at a higer level num: This means the next node is lower in the tree and is a child of the last element added. Recursively call addChildrenNodes using the new level number and passing in the last element added as the parent. Advance the nodeIndex to whatever AddChildrenNodes tells us to.
- The next node is at a lower level num: This means we are done with this branch — so return the current nodeIndex.
- We run out of data: in this case we are done with our tree, return the current nodeIndex.
Wrapping things up in a helper
This is a lot of code to remember and I always say that a line of code is a bug waiting to happen. Plus we don’t want to violate DRY (don’t repeat yourself), so create the following helper in TreeHelper:
module TreeHelper
def yui_build_tree(tree_id, tree_data)
return "//<![CDATA[ n" +
"function addChildrenNodes(currLevel, nodeIndex, parent) { \n" +
"var lastNode;\n"+
"var level = currLevel;\n"+
"while (nodeIndex < #{tree_data}.length) {\n"+
"var level = #{tree_data}[nodeIndex];\n"+
"if (level == currLevel) {\n"+
"nodeIndex++;\n"+
"lastNode = new YAHOO.widget.TextNode(#{tree_data}[nodeIndex++], parent, false);\n"+
"} else if (level < currLevel) {\n"+
"return nodeIndex;\n"+
"} else {\n"+
"nodeIndex = addChildrenNodes(level, nodeIndex, lastNode);\n"+
"}\n"+
"}\n"+
"return nodeIndex;\n"+
"}\n"+
"function #{tree_id}_Init() {\n"+
"var tree = new YAHOO.widget.TreeView(\"#{tree_id}\");\n"+
"addChildrenNodes(0, 0, tree.getRoot());\n"+
"tree.draw();\n"+
"}\n"+
"YAHOO.util.Event.addListener(window, \"load\", #{tree_id}_Init);\n"+
"//]]>";
end
end
Once we have this helper, we can now replace display.rhtml with:
<html>
<head>
<title>YUI Tester: <%= controller.action_name %></title>
<%= javascript_include_tag "yui/yahoo",
"yui/dom",
"yui/event",
"yui/connection",
"yui/dragdrop",
"yui/treeview"%>
<%= stylesheet_link_tag 'yui/tree'%>
<%= stylesheet_link_tag 'appstylesheet'%>
</head>
<body>
<div id="mytree"></div>
<script type="text/javascript">
//<![CDATA[
var test_data =
[0, { label: "Cat 1", href:"http://www.yahoo.com" },
1, { label: "Cat 1.1", href:"http://www.yahoo.com" },
1, { label: "Cat 1.2", href:"http://www.yahoo.com" },
2, { label: "Cat 1.2.1", href:"http://www.yahoo.com" },
2, { label: "Cat 1.2.2", href:"http://www.yahoo.com" },
1, { label: "Cat 1.3", href:"http://www.yahoo.com" },
0, { label: "Cat 2", href:"http://www.yahoo.com" }];
//]]>
<%= build_tree("mytree", "test_data") %>
</script>
</body>
Next Steps
As you can see from this example, I am still hardcoding the data. The next thing to do would be to hook this up to a model object and create a helper that generates the tree data structure. I recommend leveraging the methods from “act_as_tree” in the helper. The other thing that would be nice would be adding drag and drop to re-arrange the tree structure. Hmm…. guess I better get back to it to figure out how to do that
9 Comments Add your own
1. HowToWorkWithTheYUI in Ru&hellip | July 16th, 2006 at 7:25 pm
2. RoR Wiki ËÝÌõ Wiki - HowT&hellip | July 20th, 2006 at 9:50 am
3. Sonjaya Tandon » HO&hellip | August 9th, 2006 at 12:18 am
[…] Before you begin with this tutorial, make sure you have gone through HOW-TO: Integrate a YUI tree with Rails. This tutorial picks up where that one left off. […]
4. HowToWorkWithTheYUI (Vers&hellip | August 24th, 2006 at 3:04 am
5. sheynkman | December 19th, 2006 at 4:58 pm
If you want to see a site built completely with Ruby/Rails/YUI and YUI-ext, check out the one I built: HouseMath 2.0. I still have prototype in there for rails’ sake, but other than that, it’s YUI with lots of rails helpers.
6. sonjaya | December 20th, 2006 at 9:32 am
I checked out your site sheynkman. Looks like you put a good amount of work into that. Site looks great, btw.
7. luan nguyen | February 24th, 2007 at 7:19 pm
I have a banner, sidebar, and main div(s).
I am using yui tree view on my sidebar. When user click on my sidebar, it goes to appropriate controller.
The problem that I have is that my yui tree view sidebar collapse whenever I click on the sidebar. It seems like the whole page get refreshed.
What would I do so that the sidebar doesn’t get refreshed when I click on it.
Thanks a lot.
Luan
Here is my views/layouts/application.rhtml
Test
“all”%>
// ‘test1′, :action => ‘list’) %>” },
1, { label: “Cat1.2″, href:” ‘test2′, :action => ‘list’) %>” },
0, { label: “Cat 2″},
1, { label: “Cat 2.1″, href:” ‘test3′, :action => ‘list’) %>” },
1, { label: “Cat 2.2″, href:” ‘test4′, :action => ‘list’) %>” }];
//]]>
8. StumbleUpon » Your p&hellip | April 11th, 2007 at 3:37 am
9. links for 2007-04-27 &laq&hellip | April 27th, 2007 at 4:32 pm
[…] Sonjaya Tandon » HOW-TO: Integrate a YUI tree with Rails (tags: rubyonrails YUI tree javascript) […]
10. LeonardoBighi.com - Progr&hellip | June 16th, 2008 at 8:10 pm
Leave a Comment
You must be logged in to post a comment.
Trackback this post | Subscribe to the comments via RSS Feed