Blog do Urubatan
msgbartop
Desenvolvedor, Palestrante, Escritor, Nerd Assumido e Pai do Marcus :D
msgbarbottom

02 May 08 Autocomplete para rails com jquery muito fácil!

No último projeto que estou trabalhando, resolvi utilizar jQuery em vez do prototype padrão …

E eu precisava de um campo de texto com auto completar, e mesmo que estivesse utilizando o prototype, não seria muito fácil utilizar o plugin de autocomplete do rails por que eu precisava deste auto complete em um campo de texto que existe diversas vezes dentro do mesmo form, e novos são adicionados via RJS, isto complicava muito a minha vida por que o ID destes campos adicionados automagicamente é o mesmo …

Como estava utilizando o jQuery, atravéz do plugin jRails isto se tornou muito fácil, bastou utilizar o plugin suggest do proprio jQuery

O processo para habilitar este autocomplete é bem simples como vocês podem ver abaixo.
Primeiro, instalando o plugin jRails:

script/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails
rake jrails:install:javascripts

Com isto podemos começar a brincar com os plugins do jQuery, para utilizar o plugin suggest, basta fazer o download dele, colocar o css na pasta public/stylesheets e o js na pasta public/javascripts da aplicação …
Ai vamos editar o layout padrão da aplicação, e ter certeza de que ele inclui as seguintes linhas:

1
2
3
  <%= stylesheet_link_tag 'jquery.suggest.css' %>
  <%= javascript_include_tag :defaults %>
  <%= javascript_include_tag "jquery.suggest.js" %>

Depois disto, em qualquer formulário, para ativar o suggest, basta colocar um text_field padrão do rails com o seguinte código (este bloco veio de dentro de um form_for):

1
 <%= inf.text_field :name, :onfocus => "$(this).suggest('#{formatted_examples_url(:js)}')", :index => nil %>

assim, o suggest vai ser ativado para este campo quando o usuário entrar no campo, independente de se ja existe outro campo com o mesmo ID (sim, eu sei que não deveriam existir objetos com o mesmo ID, mas neste caso não tenho muito como evitar isto … )
Agora no controller …
Tenho o controller examples mapeado como um resource padrão no rails, e editei o método index dele para ficar parecido com isto:

1
2
3
4
5
6
7
8
9
  def index
    @examples = Example.paginate :page => params[:page], :conditions => ["name like ?","%#{params[:q]}%"]
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @examples }
      format.js
    end
  end

basicamente a única alteração do controller padrão foi adicionar a linha format.js e adicionei a condition para filtrar a consulta …
depois disto criei o arquivo “index.js.erb” com o seguinte conteúdo (sim, eu podia fazer um render :inline mas não gosto muito da idéia :D )

1
<%= @examples.collect(&:name).join("\n") %>

fazendo com que o resultado desta action quando chamada com a extensão “js” fosse apenas uma listagem com um nome por linha …

Tudo pronto, autocomplete funcionando :D
Achei mais simples do que o plugin padrão do rails para autocomplete :D

PS.: cada vez eu acho o jQuery mais legal de trabalhar, to curtindo mais ele do que o prototype.

If you enjoyed this post, make sure you subscribe to my RSS feed!

Tags: , , ,

Reader's Comments

  1. |

    Muito interessante. Sempre preferi usar o JQuery ao invés do prototype, e agora que estou começando com rails vou dar uma olhada nesse plugin.

    Reply to this comment
  2. |

    [...] Simplicação de código no uso do Rails ao invés do Prototype por Urubatan [...]

    Reply to this comment
  3. |

    Urubatan, o que tem no helper formatted_examples_url(:js) ?

    Abraço!

    Reply to this comment
  4. |

    É um helper padrão de rotas nomeadas REST do rails 2.x+
    neste caso ele só vai renderizar a URL /examples.js

    Reply to this comment
  5. |

    Otimo.
    para fazer com o prototype dava uma cançeira danada.
    vou tentar com JQuery
    abraços

    Reply to this comment
  6. |

    Nossa uma vez tentei fazer esse autocomplete com prototype.
    muuuito trabalho
    agora segui esse seu post O.o
    funcionou de primiera
    vlw

    Reply to this comment
  7. |

    então, não tem para wordpress???
    na forma de plugin???

    Reply to this comment
  8. |

    Sou iniciante em Rails e gostaria de saber como pegar o conteúdo gerado por uma def e usá-lo como fonte de dados para o suggest?

    Por exemplo, no meu controller eu criar:
    def suggest
    end

    e pegar o conteúdo gerado para passar como fnte de dados para o autocomplete.

    Obrigado

    Reply to this comment
  9. |

    Maneiro era o que estava procurando =D

    abraço

    Reply to this comment
  10. |

    Cara…
    Gostei dessa…
    Melhor mesmo q o prototype…

    Só q ja fiz o projeto inteiro em prototype, sei q posso usar os dois…
    Mas vou ter q carregar mais um .js….
    Vai ficar apesado !
    :(

    Reply to this comment
  11. |

    Blz Urubatan?

    Estou com dificuldade para implementar o codigo acima.

    Nao entendi a seguinte parte

    “$(this).suggest(‘#{formatted_examples_url(:js)}’)”, :index => nil %>

    O que seria o formatted_examples_url(:js) ?

    Vlw

    Reply to this comment
    • |

      formatted_examples_url é uma chamada do rails que retorna a URL para o controller “examples” para o content type especificado, neste caso javascript.
      mas se não me engano este método vai deixar de existir no rails 3.0 :D

      Reply to this comment
  12. |

    Interesante eu fiz todo o tutorial, porém o meu não carregou, é como se ele não estivesse renderizando quando digito o que quero buscar no text field.

    Eu acesso o arquivo categorias.js e ele lista tudo, mas quando digito no text_field não aparece nada, me dá um help. :)

    Código index.js.erb

    Formulario no partial
    “$(this).suggest(‘#{categorias_url(:js)}’)”, :index => nil%>

    Controller Categorias
    @categorias = Categoria.find(:all, :conditions => ["descricao like ?","%#{params[:q]}%”])

    e embaixo o format.js

    Reply to this comment
  13. |

    Cara, acho q to sendo meio noob.
    Não entendi muito bem não;

    vou colocar minha dúvida :

    Tenho o controller : new

    class NewController < ApplicationController

    def list

    end

    end

    na minha view List tem :

    ‘listaname’,:html => {:id => “form” , :name => “form”}, :url=>{:action=>’listing’, :id=>@item } do %>

    No caso tenho alguns campos que preciso de auto complete.

    São eles :

    ===> esse é referente a tabela news

    ===> esse é referente a tabela sectors

    ===> esse é referente a tabela fonts

    Como devo proceder nesses casos?

    Reply to this comment

Leave a Comment