RailsTree 0.8.5
Tuesday, July 10th, 2007Estava procurando uma tree para utilizar em rails e não achei, aí migrei a tree que tinhamos desenvolvido baseado no javascript do Geir Landr[2003] do formj para um plugin rails.
Exemplo de árvore dos dois estilos por padrão.
Gnome Style(default)

Explorer Style

Mac X/Acqua Style
Me mande que coloco aqui ![]()
Anatomia
Após a instalação o railstree adiciona os seguintes arquivos no RAILS_ROOT
/lib/node.rb # o nó /lib/tree.rb # a tree que também é um nó(raíz) /public/images/tree/*.gif # imagens(pasta,documento,etc) /public/javascripts/tree.js # O script da árvore /public/stylesheets/tree.css # humm! o estilo.
Talvez o estilo da sua aplicações interfira diretamente no esboço da árvore.
Gnome Style é o default, para usar o Explorer Style descompacte img_tree_explorer.tar.gz em /public/images/tree
Instalação
Via svn
Adicione o repositório
script/plugin source svn://rubyforge.org/var/svn/railstree/vendor/plugins
Depois instale com
script/plugin install tree
Via local
Descompacte o arquivo railstree0.8.5.zip no diretório vendor/plugins do seu Rails. Entre no diretório tree e execute
ruby install.rb
O railstree funciona em conjunto com os scripts de ajax e javascripts default do rails, portando adicione na sua view o no seu layout os scripts
<%= javascript_include_tag 'prototype' %> <%= javascript_include_tag 'effects' %> <%= javascript_include_tag 'dragdrop' %> <%= javascript_include_tag 'controls' %>
e depois o script e o css do railstree
<%= stylesheet_link_tag 'tree' %> <%= javascript_include_tag 'tree' %>
ficando assim
<%= stylesheet_link_tag 'tree' %> <%= javascript_include_tag 'tree' %> <%= javascript_include_tag 'prototype' %> <%= javascript_include_tag 'effects' %> <%= javascript_include_tag 'dragdrop' %> <%= javascript_include_tag 'controls' %>
Já tá pronto pra funcionar
Usando
A idéia é básica. Um nó pode ter filhos ou não. Para criar sua estrutura siga sempre a lógica de colocar um nó dentro do outro e um objeto da classe Tree para impressão dos dados na tela.
Exemplo:
a=Node.new(:label => 'A', :url => '/letras/a') # nome , link b=Node.new(:label => 'B', :url => '/letras/b') c=Node.new(:label => 'C', :url => '/letras/c') d=Node.new(:label => 'D', :url => '/letras/d') e=Node.new(:label => 'E', :url => '/letras/e') f=Node.new(:label => 'F', :url => '/letras/f') # nó em filho a << b #adicionando b em a c << a #adicionando a em c d << e #adicionando e em d tree=Tree.new(:label => 'Root',:url=> '/letras/todas') tree << c #Taca 'c' na raiz da tree tree << d #Taca 'd' na raiz da tree tree << f #Taca 'f'(sem filho) na raiz da tree
Podemos passar blocos para os nós. Exemplo da mesma estrutura acima, usando blocos
tree=Tree.new(:label => "Root",:url =>"/letras/todas") do |t| t << Node.new(:label => "C",:url =>"/letras/c") do |n| n << Node.new(:label => "A",:url =>"/letras/a") {|a| a << Node.new(:label => "B",:url =>"/letras/b")} end end tree << Node.new(:label => "D",:url =>"/letras/d") {|d| d << Node.new(:label => "E",:url =>"/letras/E") } tree << Node.new(:label => "F",:url =>"/letras/f")
E que Deus continue inspirando Yukihiro Matsumoto…
Vc escolhe!
Tem mais uma, todo o node tem nodes e aceita um bloco(opcional)
a=Node.new("A","/letras/a") a.nodes do |n| #faça algo com os filhos end
Personalizando…
Você poderá mudar os ícones de um nó fechado ou aberto, fazer referênciar pelo atributo href de uma âncora ou onclick para acessar uma função em javascript, falar para o nó aparecer aberto ou fechado, etc.
Mudando os ícones
a=Node.new(:label => "A",:url => "/letras/a") a.icon='/images/db.png' a.icon_open='/images/outroicone.png'
Exemplo, esse código
tabelas1=%w(starttelephony startvoip customers gateways) tabelas2=%w(teste1 teste2 ) d1=Node.new(:label => "radius", :icon => "/images/data.png", :open => true) d2=Node.new(:label => "teste", :icon => "/images/data.png", :open => false) tabelas1.each do |t| no=Node.new(:label => t, :icon => "/images/table_sql.png") d1 << no end tabelas1.each do |t| no=Node.new(:label => t, :icon => "/images/table_sql.png") d1 << no end tabelas2.each do |t| no=Node.new(:label => t, :url => 'link aqui', :icon => "/images/table_sql.png") d2 << no end tr = Tree.new(:label => "Databases[solaris]") tr << d1 tr << d2
Gera isto:

Falando para um node aparecer aberto ou fechado(se tiver filhos!)
# :open => true ou false, esse valor é passado para o javascript a=Node.new(:label => "A",:url => "/letras/a", :open => true) #ou a.open=true
Link e eventos
Temos o atributo variável event_name que pode ser qualquer coisa que vc quer mais trabalha em conjunto com o atributo href, não obstante para criar um link teremos o seguinte:
Node.new(:label => "A",:url => "/letras/a")
é a mesma coisa de fazer isso
Node.new(:label => "A",:href => '/letra/a', :event_name => :href)
isso vai criar uma tag assim para o nó
<a href=’/letras/a’ > A </a>
Hummm!
Então para criar um nó que chama um javascript pode ser assim
Node.new(:label => "A", :url => "alert('nossa que doído!')", :event_name => :onclick ) #ou a=Node.new a.label="A" a.url="alert('nossa que doído!')" a.event_name= :onclick
Link for Rails
Tem um esquema legal, que é usar a mesmo mecanismo de link do Rails o link_to e o link_to_remote.
É necessário a adição da opção :base referenciando uma instância de qualquer controller para que o mecanismo interno do método url_for(rails) funcione adequadamente.
link_to
Node.new :label => "Criar usuário", :link_to => { :base => @controller, :controller => "usuarios", :action => "adicionar" , :id => 1 }
assumindo que @controller é uma instância do controller, se tiver dentro de um controller troque @controller por self ficando :base => self.
Para um roteamento padrão do Rails isso é a mesmo coisa de
n=Node.new(:label => "Criar usuário",url => "/usuarios/adicionar/1")
Pode também fazer requisições em ajax utilizando a criação padrão do link_to_remote mais :base.
link_to_remote
Node.new :label => "Adicionar usuário ", :link_to_remote => { :base => @controller, :controller => "usuarios", :update => "id_do_div", :url =>{ :action => 'adicionar', :c=> 'variavel C', :a => 'variavel A'} } }
Montando uma árvore de diretório
Vou demonstrar aqui gerando o path do RAILS_ROOT
Tree.for(RAILS_ROOT)
Pronto. Isso gera

Extra Sintaxe
t=Tree.new(:label => 'Raiz') t.child(:label => 'Pai').child(:label => 'filho').child(:label => 'espirito santo').child(:label => 'amem')
t.child(:label => 'Pai'){ |p| p.child(:label => 'filho') } #ou t.child Node.new(:label => 'Pai').child Node.new(:label => 'filho')
Para vários irmão
t.child Node.new(:label => 'a'),Node.new(:label => 'b'), Node.new(:label => 'c')
ou
t.mknodes(5) do |n,s| n.label="Link #{s}" n.url="/link/#{s}" end
Obs.: Sugestão do Ronie Uliana
Obs2.: Criação dos nodes passando Hash foi sugestão do Marcelo Júnior

