Autocomplete nativo do Cake (Ajax Helper)
Autor: Carlitos | Publicado: 2011-02-05T11:20:00-03:00

Eu já havia mostrado uma implementação de autocomplete no Cake usando o jQuery UI (http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html), mas nunca havia usado o autocomplete nativo dele que utiliza o Prototype e o Scriptaculos. Até porque não tenho muita familiaridade com essas outras bibliotecas e gosto muito dos temas prontos do jQuery UI, o que dispensa dores de cabeça com o CSS.

Bom vamos nessa então...

Antes de começarmos veja nos posts anteriores como criar uma tabela de "cidades" (no meu caso, com os campos: id, estado_id, cidade) e crie para ela o model, views e controller usando o bake.

1º) Seguindo o book (http://book.cakephp.org/view/1370/autoComplete) crie a action autoComplete() no controller ...app/controllers/cidades_controller.php. 
function autoComplete(){
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;layout = 'ajax';
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $cidades = $this-&gt;Cidade-&gt;find('all', array(
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'conditions' =&gt;&nbsp;&nbsp;&nbsp; array('Cidade.cidade LIKE' =&gt; $this-&gt;data['Cidade']['cidade'] . '%'),
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'order' =&gt; array('Cidade.cidade'),
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'fields' =&gt; array('cidade')
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;set('cidades', $cidades);
&nbsp;&nbsp;&nbsp; }
Veja que estou listando todas as cidades cujo nome comece com o argumento recebido via POST e ordeno a lista de cidades ascendentemente.

2º) Crio a view ...app/views/cidades/auto_complete.ctp:
&lt;ul&gt;
&lt;?php
&nbsp;&nbsp;&nbsp; foreach($cidades as $cidade)
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo '&lt;li&gt;' . $cidade['Cidade']['cidade'] . '&lt;/li&gt;';
?&gt;
&lt;/ul&gt;
3º) E na view ...app/views/cidades/add.ctp adicionamos o autocomplete em si:
&lt;?php
&nbsp;&nbsp;&nbsp; $javascript-&gt;link('https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js', false);
&nbsp;&nbsp;&nbsp; $javascript-&gt;link('https://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', false);&nbsp; 
&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; echo $this-&gt;Html-&gt;css('autocomplete');
?&gt;&nbsp;&nbsp;&nbsp; 
&lt;div class="cidades form"&gt;
&lt;?php echo $this-&gt;Form-&gt;create('Cidade');?&gt;
&nbsp;&nbsp;&nbsp; &lt;fieldset&gt;
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;legend&gt;&lt;?php __('Add Cidade'); ?&gt;&lt;/legend&gt;
&nbsp;&nbsp;&nbsp; &lt;?php
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo $this-&gt;Form-&gt;label('Cidade');
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo $ajax-&gt;autoComplete('Cidade.cidade', '/cidades/autoComplete');
&nbsp;&nbsp;&nbsp; ?&gt;
&nbsp;&nbsp;&nbsp; &lt;/fieldset&gt;
&lt;?php echo $this-&gt;Form-&gt;end(__('Submit', true));?&gt;
&lt;/div&gt;
Veja que o  $ajax-&gt;autoComplete('Cidade.cidade', '/cidades/autoComplete') cria um input com autocomplete, mas esse input vem sem label =/, portanto temos que gerar um label antes.

Veja também que adicionei um CSS (echo $this-&gt;Html-&gt;css('autocomplete')) &nbsp;para estilizar a lista com os resultados do autocomplete. O arquivo ...app/webroot/css/autocomplete.css ficou assim:
div.auto_complete {
    background: #003d4c;
    color: #ffffff;
}
div.auto_complete ul {
    margin:0;
    padding:0;
    width: 100%;
    list-style-type:none;
}
div.auto_complete ul li.selected {
    background-color: #62AF56;
    font-weight: bold;
}
div.auto_complete ul li {
    margin:0;
    padding:5px;
    cursor:pointer;
}

Obs.: Eu dei uma garibada no CSS que achei aqui (http://webdomino.blogspot.com/2006/08/ajax-autocompletion.html). =]

Ao acessar a aplicação em: http://&lt;seu_dominio&gt;/cidades/add e entrar com o prefixo de alguma cidade já cadastrada no banco no campo cidade, após alguns segundos (é bem rápido, acho que não chega nem a isso) a lista é carregada automagicamente* hehe!

Veja o resultado final!



Espero que tenham gostado! Qualquer dúvida é só perguntar.
Abraço!