Ext JS Tree TreeLoader with Rails
Ext JS, Ruby on Rails, Tutorials September 15th, 2008Recently I been playing around with alot of Ext JS. It’s a great Ajax Framework, which makes building a full Ajax application easy as pie. All you really need to worry about is how to transfer Json between your Rails application and Ext JS.
Here’s a tutorial on how to get Ext JS’s TreePanel going with Ruby on Rails.
Ext JS Implementation
You’ll start by creating the Tree component in your view. This is an example of how it should look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var tree = new Ext.tree.TreePanel({ useArrows:true, autoScroll:true, animate:true, containerScroll: true, // auto create TreeLoader loader: new Ext.tree.TreeLoader({dataUrl:'/groups.json', requestMethod: 'GET'}), root: new Ext.tree.AsyncTreeNode({ text: 'Root Node', draggable:false, disabled: true, expandable: false, expanded: true, id:'source' }) }); |
The most important line in this code above is line number 7. This will call the URL to retrieve the Tree in Json format. I use a GET request so it will goto my index action in Rails using a Restful design.
Rails Tree Plugin
As you may have noticed from my example I’m using Group as the model for my tree. In your model you should install a tree plugin similar to acts_as_tree so you get access to methods such as group.children.
If your using the above plugin, add this line into your model to specify your model to use the plugin:
# /app/models/group.rb class Group < ActiveRecord::Base acts_as_tree :order => "name", :dependent => :destroy .... end |
If you find acts_as_tree to be limited in functionality, there are better tree plugins that I recommend having a look at such as acts_as_nested_set
Rails Model Implementation
For my implementation I needed a boolean function to return true/false if group was a leaf node or not. I added this function into my model.
# /app/models/group.rb ... def leaf? if(children.size == 0) false else true end end ... |
Also I added a function to return the root node groups.
# /app/models/group.rb ... def self.find_root_nodes find(:all, :conditions => ["parent_id IS NULL"]) end ... |
Handling JSON requests with Rails
Using a Restful design here. I made my controller return json using .json at the end of the URL. To allow this I added this line to the end of my routes.rb file
# END OF /config/routes.rb ... map.connect ':controller/:action.:format' ... |
Rails Controller Implementation
My index action in my controller serves the GET request and spits out json when .json is supplied at the end of the URL. A extra function (get_ext_tree) is required to recursively add the children to a tree node. This function will return JSON in the format required for the Ext JS TreeLoader.
# /app/controllers/groups_controller.rb class GroupsController < ApplicationController def index groups = Group.find_root_nodes json_data = get_ext_tree(groups,nil) end respond_to do |format| format.html #/groups format.json { render :json => json_data } # /groups.json end end def get_ext_tree(groups, parent) data = Array.new groups.each { |group| if group.leaf? if data.empty? data = [{"text" => group.name, "id" => group.id, "leaf" => false, "children" => get_ext_tree(group.children,group) }] else data.concat([{"text" => group.name, "id" => group.id, "leaf" => false, "children" => get_ext_tree(group.children,group)}]) end else data.concat([{"text" => group.name, "id" => group.id, "leaf" => true, "children" => []}]) end } return data end end |
September 24th, 2008 at 6:17 pm
hi, i was often tempted by ext js as well and i might get convinced if sproutcore or similars don’t take over the world before.
Just a few remarks re ruby idioms and general best practice :
you can rewrite leaf? this way:
def leaf?
children.size != 0
end
find_root_nodes should be a named scope.
and the iterator get_ext_tree should be in the model with a little rewrite as well so it you would look lik this:
format.json { render :json => @groups.to_json_tree }
October 23rd, 2008 at 5:57 am
looking forward for more information about this. thanks for sharing. Eugene
November 13th, 2008 at 2:17 pm
xvfblivbzrtw3asc
February 15th, 2009 at 2:21 pm
Super scary. Really. Think about it.
June 12th, 2009 at 8:54 pm
Hi
I was searching for some technical stuffs related to Ruby On Rails and i found a blog ” http://railshafeez.blogspot.com/2009/02/image-uploading.html ”
This blog has copied contents from your blog. I felt that you must know about this piracy.
ThankYou
Your “Wellwisher”