Rails JsDOMenu
Para quem gosta da similiaridade de páginas web com desktop, aí vai um plugin para Rails com o estilo do Windows XP utilizando o clássico jsMenuBar. Isso me fez lembrar de um usuário que só conseguia operar o sistema por menus, link ficaria em um local obscuro da mente dele :-> .
O conceito é bem simples: cada menu pode ter MenuItens e Menus e uma MenuBar pode ter vários Menus.
Veja um menubar gerado com três menus e submenus.

Anatomia
O Rails JsDOMenu é composto pelos arquivos
/lib/menu_item.rb # MenuItem /lib/menu.rb # Menu /lib/menu_bar.rb #MenuBar /public/images/jsdomenubar/*.png # imagens para os estilo /public/stylesheets/jsdomenubar.css # o estilo. /public/javascripts/jsdomenubar.js # script da barra /public/javascripts/jsdomenu.js # script do menu.
Talvez o estilo da sua aplicações interfira diretamente no esboço do menu.
Instalação
Via svn
Adicione o repositório
script/plugin source svn://rubyforge.org/var/svn/railsmenubar/plugins
Depois instale com
script/plugin install railsmenubar
Via local
Descompacte o arquivo railsmenubar.zip no diretório vendor/plugins do seu Rails. Entre no diretório railsmenubar e execute
ruby install.rb
O jsDOMenuBar funciona em conjunto com os scripts de ajax e javascripts default do rails, portando adicione na sua view ou 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 'jsdomenubar' %> <%= javascript_include_tag 'jsdomenu' %> <%= javascript_include_tag 'jsdomenubar' %>
ficando assim
<%= stylesheet_link_tag 'jsdomenubar' %> <%= javascript_include_tag 'jsdomenu' %> <%= javascript_include_tag 'jsdomenubar' %> <%= javascript_include_tag 'prototype' %> <%= javascript_include_tag 'effects' %> <%= javascript_include_tag 'dragdrop' %> <%= javascript_include_tag 'controls' %>
Usando
Temos dois tipos de eventos(:event_type) o :code e o :link, sendo
:code => quando necessárioa execução de um script
:link => referência a uma url(default)
Veja abaixo como criar os dois tipos de eventos
m1=MenuItem.new "Mostrar mensagem de Oi!", :event_type => :code,nclick => "alert('Oi!')" m2=MenuItem.new "Ir para hashcode.eti.br", :event_type => :link,
nclick => "http://www.hashcode.eti.br" #ou m2=MenuItem.new "Ir para hashcode.eti.br",
nclick => "http://www.hashcode.eti.br"
Opções para o MenuItem
:label => A label do menu
:event_type => Tipo do evento :code ou :link
nclick => Evento ou url
:enable => Habilita ou Desabilita (true ou false)
:icon => Path do ícone
:icon_hover => Path do ícone quando estiver selecionado
Criando um objeto Menu de tamanho 200px e adicionando o m1 e o m2
menu=Menu.new("Primeiro Teste", 200) #Label e o tamanho em pixel menu << m1 menu << m2
ou passando um bloco
Menu.new("Primeiro Teste", 200) do |m| m << m1 m << m2 end
Para finalizar esse exemplo vamos criar um MenuBar e adicionar o menu a ele.
mb=MenuBar.new :width => 300 mb << m
Já está pronto para ser utilizado.
Vamos dar nome aos bois

Que esboço maravilhoso esse!! Dá pra ver tanto que sou bom com o Gimp!! O que é aquilo lá em cima do MenuItem.separator ? É uma “quase uma seta”.
Mas dá pra entender um pouco.
Podemos ampliar o desempenho programático utilizando blocos. Exemplo de criação por fechamentos.
@menu=MenuBar.new(:width => 300) do |mb| mb << Menu.new("Primeiro Teste", 200) do |m| m << MenuItem.new("Ir para hashcode.eti.br", :event_type => :link,nclick => "http://www.hashcode.eti.br") m << MenuItem.new("Mostrar mensagem de Oi!", :event_type => :code,
nclick => "alert('Oi!')") end end
Observe algo interessante… a sintaxe acima tem uma semelhança com o esboço do menu, que ao meu ver induz ao programador o resultado a ser obtido, pois sabemos que criar menus é uma coisa carinhosamente chata.
Submenus
Como o estilo da linguagem é bem elegante vejamos a criação de submenus para o menu m.
@menu=MenuBar.new(:width => 300) do |mb| mb << Menu.new("Primeiro Teste", 200) do |m| m << MenuItem.new("Ir para hashcode.eti.br",nclick => "http://www.hashcode.eti.br") m << MenuItem.new("Mostrar mensagem de Oi!", :event_type => :code,
nclick => "alert('Oi!')") m.new("Sub 1") do |s1| #método da instância s1 << MenuItem.new("Item 1!", :event_type => :code,
nclick => "alert('item 1')") s1 << MenuItem.new("Item 2!", :event_type => :code,
nclick => "alert('item 2')") end end end
pode simplificar mais ainda, utilizando os façade de cada objeto. O mesmo código anterior utilizando façades.
@menu=MenuBar.new(:width => 300) do |mb| mb.new("Primeiro Teste") do |m| m.new_item("Ir para hashcode.eti.br",nclick => "http://www.hashcode.eti.br") m.new_item("Mostrar mensagem de Oi!", :event_type => :code,
nclick => "alert('Oi!')") m.new("Sub 1") do |s1| s1.new_item("Item 1!", :event_type => :code,
nclick => "alert('item 1')") s1.new_item("Item 2!", :event_type => :code,
nclick => "alert('item 2')") end end end
E que Deus continue inspirando Yukihiro Matsumoto…
Vc escolhe!
Temos também o MenuItem separador.
m=Menu.new("Primeiro Teste", 200) m <<MenuItem.separator
Um MenuBar com dois menus seria algo assim
@menu=MenuBar.new(:width => 300) do |mb| mb.new("Primeiro") do |m| m.new_item("Ir para hashcode.eti.br",nclick => "http://www.hashcode.eti.br") m.new_item("Mostrar mensagem de Oi!", :event_type => :code,
nclick => "alert('Oi!')") m.new("Sub 1") do |s1| s1.new_item("Item 1!", :event_type => :code,
nclick => "alert('item 1')") s1.new_item("Item 2!", :event_type => :code,
nclick => "alert('item 2')") end end mb.new("Segundo") do |m| m.new_item("Faça algo 1",
nclick => "http://www.hashcode.eti.br") m.new_item("Faça algo 2", :event_type => :code,
nclick => "alert('algo 2')") m.new("Sub 1 do Segundo") do |s1| s1.new_item("Item Sub1 1!",
nclick => "http://www.hashcode.eti.br") s1.new("Sub 2 do Segundo") do |s2| s2.new_item("Sub2 1",
nclick => "http://www.hashcode.eti.br") s2.new_item("Sub2 2",
nclick => "http://www.hashcode.eti.br") end s1.new_item("Item Sub1 2",
nclick => "http://www.hashcode.eti.br") end end end
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 a uma instância de qualquer controller(geralmente self ou @controller) para que o mecanismo do método url_for do Rails funcione adequadamente.
link_to
item1=MenuItem.new item1.link_to "Criar usuário", :base => self, :controller => "usuarios", :action => "adicionar" , :id => 1 m=Menu.new("Usuário") m << item1
ou
item1=MenuItem.new.link_to "Criar usuário", :base => self, :controller => "usuarios", :action => "adicionar" , :id => 1 m=Menu.new("Usuário") m << item1
ou tudo junto!!
Menu.new("Usuário").new_item.link_to "Criar usuário", :base => self, :controller => "usuarios", :action => "adicionar" , :id => 1
Dá até gosto de programar nessa linguagem!!
link_to_remote
Utiliza-se ajax da mesma forma que o link_to mas com parametros diferentes(claro né Shairon!).
Exemplo:
item1=MenuItem.newitem1.link_to_remote "Teste Ajax", :base => self, :controller => "usuarios", :update => "id_do_div", :url =>{:action => "adicionar", :c=> 'variavel C', :a => 'variavel A'}
Use e Abuse!!
Uruuuuuuuuuu, sou o primeiro a comentar.
Muito bom mesmo cara.
Realmente um script de responsa
Opa, será que você pode botar o source desse exemplo pra download?
Lá em cima railsmenubar.zip
Na verdade eu queria ver o código do controller e do view desse exemplo, pra mim ver no meu browser como fica. Nas figuras que você colocou eu achei muito bom, mas eu ainda não sou novato no mundo rails e não consegui reproduzir aqui. Se você puder compactar a pasta desse projeto exemplo e colocar aqui seria ótimo
Cara, blz?
Achei bacana a solução que vc criou, mas não esotu conseguindo testar. Desculpe a minha ignorânica, mas sou aprendiz de estagiário em Rails…
Eu já coloquei o código no Layout, agora eu crio o Menu no Controller? E onde eu coloco a chamada do Menu na View?
Seria legal se vc colocasse um exemplo de uma pequena aplicação que só cria o menu bar …
Abraços.
Alexandre.
Uma forma simples
menutest-rails1.1.6.zip
Maravilha! Minha duvida era a mesma do Alexandre Campos… Agora já substitui a gambiarra que eu usava e to com um menu bonito e com cara profissional no meu app. muito obrigado
eu sou novo em rails, e o exemplo da erro em ie6, gostaria saber como solucionar.
obrigado.
Cara, o menu é bem legal, mas no IE6 o menu não aparece, somente a menu bar é visualizado… Já no FireFox o menu aparece de boa…
Alguma configuração deve ser feita?
Cara deve ter mas eu não sei o que
Muito legal!,
teria como alterar a cor da fonte do menu ou item quando
estiver :enable => false
?
Um abraço,
Evandro
Aqui nao funcionou nem no ie7 só no firefox mesmo!
Evandro