<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9151990965170112620</id><updated>2012-01-26T21:58:40.819-03:00</updated><category term='jqueryui'/><category term='cakebook'/><category term='javascript'/><category term='php'/><category term='vendor'/><category term='ajax'/><category term='exportar dados'/><category term='maskedinput'/><category term='bakery'/><category term='auth'/><category term='autocomplete'/><category term='blog'/><category term='logo'/><category term='helper ajax'/><category term='jquery'/><category term='css'/><category term='mascara'/><category term='componentes'/><category term='meiomask'/><category term='cakephp'/><category term='forms'/><category term='components'/><category term='maps'/><category term='json'/><category term='google'/><title type='text'>Cake na veia</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-3800682775345267816</id><published>2011-03-08T17:45:00.000-04:00</published><updated>2011-03-08T17:45:43.693-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='mascara'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='maskedinput'/><title type='text'>Como usar "máscaras" em campos de formulário do Cake com plugin maskedinput pra jQuery</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-8RWSXrl_W5g/TXadzCkRgEI/AAAAAAAAARA/2f8BIa8Q3Qg/s1600/title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="286" src="https://lh4.googleusercontent.com/-8RWSXrl_W5g/TXadzCkRgEI/AAAAAAAAARA/2f8BIa8Q3Qg/s320/title.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="https://lh4.googleusercontent.com/-8RWSXrl_W5g/TXadzCkRgEI/AAAAAAAAARA/2f8BIa8Q3Qg/s1600/title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;No post anterior mostrei &lt;a href="http://cakenaveia.blogspot.com/2011/03/como-usar-mascaras-em-campos-de.html"&gt;como usar "máscaras" em campos de formulário do Cake com plugin meioMask pra jQuery&lt;/a&gt;. Hoje vou mostrar um outro plugin que faz basicamente a mesma coisa, porém ele mostra a "máscara", digamos assim, assim que damos um &lt;b&gt;focus&lt;/b&gt; no campo. Por isso gosto e uso muito ele. Trata-se do maskedinput (&lt;a href="http://digitalbush.com/projects/masked-input-plugin/"&gt;http://digitalbush.com/projects/masked-input-plugin/&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Bom, antes de começar dá um play nesse som =]&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;object height="132" width="353"&gt;&lt;embed src="http://www.goear.com/files/external.swf?file=07a2af1" type="application/x-shockwave-flash" wmode="transparent" quality="high" width="353" height="132"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;1) Primeiramente fazemos o download do plugin maskedinput através do link&amp;nbsp;&lt;a href="http://digitalbush.com/projects/masked-input-plugin/"&gt;http://digitalbush.com/projects/masked-input-plugin/&lt;/a&gt;. Eu baixei a versão 1.2.2 minified. Salvando o script em app/webroot/js;&lt;br /&gt;&lt;br /&gt;2) Em uma view qualquer (escolhi a app/views/users/add.ctp) gerada via BAKE eu criei três campos: dtNasc, cpf e hora. Vejam:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;//... app/views/users/add.ctp&lt;br /&gt;...&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('dtnasc',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Data de Nascimento'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('cpf',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'CPF'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('hora',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Hora'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;...&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;3) Adiciono os scripts (jQuery e o plugin) na view. Vejam:&lt;/div&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;//... app/views/users/add&lt;br /&gt; $javascript-&amp;gt;link(&lt;br /&gt;  array(&lt;br /&gt;   'https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js', &lt;br /&gt;   'jquery.maskedinput'&lt;br /&gt;  ), &lt;br /&gt; false);&lt;br /&gt;...&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;4) Conforme falei no post anterior usaremos os IDs dos campos para que o jQuery "os encontre" no DOM. Então setamos as máscaras para cada campo, para isto usamos a função &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mask()&lt;/span&gt;. Vejam:&lt;/div&gt;&lt;/div&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;//... app/views/users/add.ctp&lt;br /&gt;...&lt;br /&gt; $javascript-&amp;gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;   $("#UserDtnasc").mask("99/99/9999");&lt;br /&gt;   $("#UserCpf").mask("999.999.999-99");&lt;br /&gt;   $("#UserHora").mask("99:99");&lt;br /&gt;  });&lt;br /&gt; ', array('inline' =&amp;gt; false));&lt;br /&gt;...&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5) Pronto! Simples não? Repare que ao colocar o cursor do mouse sobre os campos a "máscara" já é mostrada. Isso facilita muito para o usuário, uma vez que ele já prevê como os valores serão formatados (mascarados). Vejam o código final da view:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&amp;lt;?php&lt;br /&gt;//... app/views/users/add.ctp&lt;br /&gt; $javascript-&amp;gt;link(&lt;br /&gt;  array(&lt;br /&gt;   'https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js', &lt;br /&gt;   'jquery.maskedinput'&lt;br /&gt;  ), &lt;br /&gt; false);&amp;nbsp;&lt;br /&gt; $javascript-&amp;gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;   $("#UserDtnasc").mask("99/99/9999");&lt;br /&gt;   $("#UserCpf").mask("999.999.999-99");&lt;br /&gt;   $("#UserHora").mask("99:99");&lt;br /&gt;  });&lt;br /&gt; ', array('inline' =&amp;gt; false));&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;div class="users form"&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;create('User');?&amp;gt;&lt;br /&gt; &amp;lt;fieldset&amp;gt;&lt;br /&gt;   &amp;lt;legend&amp;gt;&amp;lt;?php __('Add User'); ?&amp;gt;&amp;lt;/legend&amp;gt;&lt;br /&gt; &amp;lt;?php&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('dtnasc', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Data de Nascimento'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('cpf', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'CPF' &lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('hora', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Hora' &lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt; ?&amp;gt;&lt;br /&gt; &amp;lt;/fieldset&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;end(__('Submit', true));?&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Bom, espero que tenham gostado! Apesar de ser "perfumaria", muitas vezes os recursos de máscara facilitam a vida do usuário. Só não pode esquecer de tratar os dados no server-side, pois o usuário pode estar com o javascript desabilitado, ok? =P&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-3800682775345267816?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/3800682775345267816/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/03/como-usar-mascaras-em-campos-de_08.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/3800682775345267816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/3800682775345267816'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/03/como-usar-mascaras-em-campos-de_08.html' title='Como usar &quot;máscaras&quot; em campos de formulário do Cake com plugin maskedinput pra jQuery'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-8RWSXrl_W5g/TXadzCkRgEI/AAAAAAAAARA/2f8BIa8Q3Qg/s72-c/title.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-5513982024523624170</id><published>2011-03-07T18:22:00.001-04:00</published><updated>2011-03-07T18:26:00.194-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mascara'/><category scheme='http://www.blogger.com/atom/ns#' term='forms'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='meiomask'/><title type='text'>Como usar "máscaras" em campos de formulário do Cake com plugin meioMask pra jQuery</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-N2Mpm5PjQYY/TXVI8-a5Y5I/AAAAAAAAAQ4/4EkBMPTrEkQ/s1600/title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="https://lh6.googleusercontent.com/-N2Mpm5PjQYY/TXVI8-a5Y5I/AAAAAAAAAQ4/4EkBMPTrEkQ/s320/title.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Tá precisando colocar umas máscaras em campos de formulário? Não precisa ficar quebrando a cabeça com um monte de javascript. Existem muitos plugins prontos para jQuery e outras bibliotecas.&lt;br /&gt;O plugin meioMask (&lt;a href="http://plugins.jquery.com/project/meioMask"&gt;http://plugins.jquery.com/project/meioMask&lt;/a&gt;)&amp;nbsp;é uma excelente iniciativa brazuca do pessoal do MeioCódigo.com. Esse plugin para jQuery é bem flexível, veja como usá-lo em&amp;nbsp;&lt;a href="http://www.meiocodigo.com/projects/meiomask/"&gt;http://www.meiocodigo.com/projects/meiomask/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bom, mãos na massa!&lt;br /&gt;&lt;br /&gt;1) O primeiro passo é entrar no site do meiomask e baixar a útltima versão estável do script e salvá-lo em: app/webroot/js. No meu caso baixei a versão&amp;nbsp;1.1.3&lt;span class="Apple-style-span" style="font-family: Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&amp;nbsp;(comprimida) e salvei com o nome "jquery.meio.mask.min.js";&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Verdana, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;2) Peguei uma view qualquer (escolhi a app/views/users/add.ctp) previamente gerada pelo BAKE que possui um formulário com os seguintes campos: DtNasc, CPF e Hora (não me pergunte pra que raio de cadastro é esse... coloquei só pra exemplificar os casos =]), vejam:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;// ...app/views/users/add.ctp  &lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('dtnasc',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Data de Nascimento'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('cpf',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'CPF'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('hora',&lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Hora'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3) Agora adiciono o jQuery e o script do plugin meiomask na view, vejam:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;// ...app/views/users/add.ctp&lt;br /&gt; $javascript-&amp;gt;link(&lt;br /&gt;  array(&lt;br /&gt;   'https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js',&lt;br /&gt;   'jquery.meio.mask.min'&lt;br /&gt;  ),&lt;br /&gt; false);&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4) Logo em seguida, adicionamos um "bloco de código" setando as máscaras para os campos do formulário usando o ID do campo para isso.&lt;br /&gt;&lt;blockquote&gt;OBS: O&amp;nbsp;Form&amp;nbsp;Helper do Cake sempre gera um ID para cada campo criado seguindo o padrão &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;id="ModelCampo"&lt;/span&gt;. No nosso caso o model é o &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;User &lt;/span&gt;&lt;/b&gt;e temos os campos &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Dtnasc&lt;/span&gt;&lt;/b&gt;, &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Cpf &lt;/span&gt;&lt;/b&gt;e &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Hora&lt;/span&gt;&lt;/b&gt;, o que gera os ids: UsersDtnasc, UserCpf e UserHora. O jQuery usa o '#' para referenciar IDs no DOM.&lt;/blockquote&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;// ...app/views/users/add.ctp&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt; $javascript-&amp;gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;   $("#UserDtnasc").setMask("39/19/2999");&lt;br /&gt;   $("#UserCpf").setMask("999.999.999-99");&lt;br /&gt;   $("#UserHora").setMask("29:59");&lt;br /&gt;  });&lt;br /&gt; ', array('inline' =&amp;gt; false));&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5) Feito isto é só acessar o .../users/add e verificar o resultado ao entrar com números nos campos. Veja que ele permite apenas a entrada de números e adiciona automaticamente os pontos, barras e etc, que foram setados no molde da máscara. O código final ficou assim:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&amp;lt;?php&lt;br /&gt;// ...app/views/users/add.ctp&lt;br /&gt; $javascript-&amp;gt;link(&lt;br /&gt;  array(&lt;br /&gt;   'https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js', &lt;br /&gt;   'jquery.meio.mask.min'&lt;br /&gt;  ), &lt;br /&gt; false);&lt;br /&gt;$javascript-&amp;gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;   $("#UserDtnasc").setMask("39/19/2999");&lt;br /&gt;   $("#UserCpf").setMask("999.999.999-99");&lt;br /&gt;   $("#UserHora").setMask("29:59");&lt;br /&gt;  });&lt;br /&gt; ', array('inline' =&amp;gt; false));&lt;br /&gt; ?&amp;gt;&lt;br /&gt;&amp;lt;div class="users form"&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;create('User');?&amp;gt;&lt;br /&gt; &amp;lt;fieldset&amp;gt;&lt;br /&gt;   &amp;lt;legend&amp;gt;&amp;lt;?php __('Add User'); ?&amp;gt;&amp;lt;/legend&amp;gt;&lt;br /&gt; &amp;lt;?php&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('dtnasc', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Data de Nascimento'&lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('cpf', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'CPF' &lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt;  echo $this-&amp;gt;Form-&amp;gt;input('hora', &lt;br /&gt;   array(&lt;br /&gt;    'label' =&amp;gt; 'Hora' &lt;br /&gt;   ) &lt;br /&gt;  );&lt;br /&gt; ?&amp;gt;&lt;br /&gt; &amp;lt;/fieldset&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;end(__('Submit', true));?&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;Eu particularmente uso outro plugin para máscaras (que mostrarei no próximo tópico), mas o meioMask é uma excelente alternativa além de ser brasileiro.&lt;br /&gt;&lt;br /&gt;Espero que seja útil! Abração!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-5513982024523624170?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/5513982024523624170/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/03/como-usar-mascaras-em-campos-de.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/5513982024523624170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/5513982024523624170'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/03/como-usar-mascaras-em-campos-de.html' title='Como usar &quot;máscaras&quot; em campos de formulário do Cake com plugin meioMask pra jQuery'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-N2Mpm5PjQYY/TXVI8-a5Y5I/AAAAAAAAAQ4/4EkBMPTrEkQ/s72-c/title.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-4412721136669599357</id><published>2011-02-05T11:20:00.000-03:00</published><updated>2011-02-05T11:20:50.327-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='helper ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='cakebook'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='autocomplete'/><title type='text'>Autocomplete nativo do Cake (Ajax Helper)</title><content type='html'>Eu já havia mostrado uma implementação de autocomplete no Cake usando o jQuery UI (&lt;a href="http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html"&gt;http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html&lt;/a&gt;), 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.&lt;br /&gt;&lt;br /&gt;Bom vamos nessa então...&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;1º) Seguindo o book (&lt;a href="http://book.cakephp.org/view/1370/autoComplete"&gt;http://book.cakephp.org/view/1370/autoComplete&lt;/a&gt;) crie a action &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;autoComplete()&lt;/span&gt; no controller ...app/controllers/cidades_controller.php. &lt;br /&gt;&lt;pre class="brush: php"&gt;function autoComplete(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;layout = 'ajax';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $cidades = $this-&amp;gt;Cidade-&amp;gt;find('all', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'conditions' =&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; array('Cidade.cidade LIKE' =&amp;gt; $this-&amp;gt;data['Cidade']['cidade'] . '%'),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'order' =&amp;gt; array('Cidade.cidade'),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'fields' =&amp;gt; array('cidade')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;set('cidades', $cidades);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;Veja que estou listando todas as cidades cujo nome comece com o argumento recebido via POST e ordeno a lista de cidades ascendentemente.&lt;br /&gt;&lt;br /&gt;2º) Crio a view ...app/views/cidades/auto_complete.ctp:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach($cidades as $cidade)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo '&amp;lt;li&amp;gt;' . $cidade['Cidade']['cidade'] . '&amp;lt;/li&amp;gt;';&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/pre&gt;3º) E na view ...app/views/cidades/add.ctp adicionamos o autocomplete em si:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js', false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', false);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Html-&amp;gt;css('autocomplete');&lt;br /&gt;?&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;lt;div class="cidades form"&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;create('Cidade');?&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;fieldset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;legend&amp;gt;&amp;lt;?php __('Add Cidade'); ?&amp;gt;&amp;lt;/legend&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Form-&amp;gt;label('Cidade');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $ajax-&amp;gt;autoComplete('Cidade.cidade', '/cidades/autoComplete');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ?&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/fieldset&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;end(__('Submit', true));?&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;Veja que o  $ajax-&amp;gt;autoComplete('Cidade.cidade', '/cidades/autoComplete') cria um input com autocomplete, mas esse input vem sem label =/, portanto temos que gerar um label antes.&lt;br /&gt;&lt;br /&gt;Veja também que adicionei um CSS (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;echo $this-&amp;gt;Html-&amp;gt;css('autocomplete')&lt;/span&gt;) &amp;nbsp;para estilizar a lista com os resultados do autocomplete. O arquivo ...app/webroot/css/autocomplete.css ficou assim:&lt;br /&gt;&lt;pre class="brush: css"&gt;div.auto_complete {&lt;br /&gt;    background: #003d4c;&lt;br /&gt;    color: #ffffff;&lt;br /&gt;}&lt;br /&gt;div.auto_complete ul {&lt;br /&gt;    margin:0;&lt;br /&gt;    padding:0;&lt;br /&gt;    width: 100%;&lt;br /&gt;    list-style-type:none;&lt;br /&gt;}&lt;br /&gt;div.auto_complete ul li.selected {&lt;br /&gt;    background-color: #62AF56;&lt;br /&gt;    font-weight: bold;&lt;br /&gt;}&lt;br /&gt;div.auto_complete ul li {&lt;br /&gt;    margin:0;&lt;br /&gt;    padding:5px;&lt;br /&gt;    cursor:pointer;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;Obs.: Eu dei uma garibada no CSS que achei aqui (&lt;a href="http://webdomino.blogspot.com/2006/08/ajax-autocompletion.html"&gt;http://webdomino.blogspot.com/2006/08/ajax-autocompletion.html&lt;/a&gt;). =]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ao acessar a aplicação em: http://&amp;lt;seu_dominio&amp;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!&lt;br /&gt;&lt;br /&gt;Veja o resultado final!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_z6epD0KXWVs/TUx3Ee5SNoI/AAAAAAAAAQw/ua_b3vgNLQk/s1600/title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_z6epD0KXWVs/TUx3Ee5SNoI/AAAAAAAAAQw/ua_b3vgNLQk/s1600/title.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_z6epD0KXWVs/TUx3D7H6fcI/AAAAAAAAAQs/uLhkn2yEvv4/s1600/Clipboard04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="208" src="http://2.bp.blogspot.com/_z6epD0KXWVs/TUx3D7H6fcI/AAAAAAAAAQs/uLhkn2yEvv4/s640/Clipboard04.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Espero que tenham gostado! Qualquer dúvida é só perguntar.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Abraço!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-4412721136669599357?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/4412721136669599357/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/autocomplete-nativo-do-cake-ajax-helper.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/4412721136669599357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/4412721136669599357'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/autocomplete-nativo-do-cake-ajax-helper.html' title='Autocomplete nativo do Cake (Ajax Helper)'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_z6epD0KXWVs/TUx3Ee5SNoI/AAAAAAAAAQw/ua_b3vgNLQk/s72-c/title.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-2796130644831133030</id><published>2011-02-03T17:58:00.000-03:00</published><updated>2011-02-03T17:58:20.672-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='helper ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>Helper Ajax com jQuery, ahan!</title><content type='html'>Estou numa empreitada testando o &lt;a href="http://book.cakephp.org/pt/view/1358/AJAX"&gt;Helper Ajax&lt;/a&gt; nativo do CakePHP e ontem, inclusive, postei um exemplo legal de como usar o método &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;observeField()&lt;/span&gt; para fazer um &lt;a href="http://cakenaveia.blogspot.com/2011/02/select-combo-estado-cidade-usando-o.html"&gt;Select Combo de Estado e Cidade&lt;/a&gt;. Lembrando que o CakePHP traz esse helper que foi criado usando as bibliotecas Prototype e Scriptaculos. Daí eu pensei: &lt;i&gt;- Poxa vida, bem que alguém poderia criar um Helper jQuery ou algo do tipo para o Cake...&lt;/i&gt; E não é que esse alguém existe, e se chama: &lt;b&gt;Damian Jóźwiak&lt;/b&gt;. Ele disponibilizou a sua criação no Bakery com um &lt;a href="http://www.cakephp.bee.pl/"&gt;link pro site&lt;/a&gt; onde tem os exemplos, download do código e até um teste de benchmark com outras bibliotecas (YUI, Dojo, etc).&lt;br /&gt;Baixei o Helper Ajax do Damian e fui fazer uns testes, vejam:&lt;br /&gt;&lt;br /&gt;Usei uma cópia da aplicação do &lt;a href="http://cakenaveia.blogspot.com/2011/02/select-combo-estado-cidade-usando-o.html"&gt;Select Combo de Estado e Cidade&lt;/a&gt;, para isto basta copiar e colar a pasta app, renomeando-a, no meu caso chamei de "appjquery". A aplicação anterior eu acesso assim: "http://localhost/cake137/" e a nova eu acesso assim: "http://localhost/cake137/appjquery".&lt;br /&gt;&lt;br /&gt;Feito isto eu extraí os arquivos: &lt;b&gt;ajax.php&lt;/b&gt; e &lt;b&gt;javascript.php&lt;/b&gt; para o diretório de helpers (&lt;b&gt;/appjquery/views/helpers/&lt;/b&gt;).&lt;br /&gt;&lt;br /&gt;Extraí também o &lt;b&gt;jquery-1.4.2.min.js&lt;/b&gt; para o diretório &lt;b&gt;/appjquery/webroot/js/&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Na minha view &lt;b&gt;appjquery/views/users/add.ctp&lt;/b&gt; eu troquei o Prototype e o Scriptaculos pelo jQuery =P:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //$javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js', false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //$javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', false); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $javascript-&amp;gt;link('jquery-1.4.2.min', false);&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pronto! Agora quem está fazendo o AJAX funcionar é o jQuery... e não precisei mudar nada as chamadas das funções.&lt;br /&gt;&lt;br /&gt;Não conheço muito o Prototype, muito menos o Scriptaculos então pra mim foi muito vantajoso esse helper. Sem contar na facilidade de integração com o jQuery UI.&lt;br /&gt;&lt;br /&gt;Bom, vi que esse helper permite muita coisa que ainda não testei. Vou começar a usá-lo a partir de agora e sempre que tiver novidades posto aqui!&lt;br /&gt;&lt;br /&gt;Vejam as imagens dele funcionando! Ah, já ia me esquecendo... fiz um teste rápido com poucos registros e o helper nativo ainda ganha um pouco em desempenho =/... mas o jQuery lançou esta semana a sua versão 1.5 e os testes mostram uma melhora execelente principalmente para o uso do AJAX e para os navegadores Chrome e Firefox 4.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_z6epD0KXWVs/TUsWwjhr1wI/AAAAAAAAAQc/_8mNJy60qU8/s1600/Clipboard01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://1.bp.blogspot.com/_z6epD0KXWVs/TUsWwjhr1wI/AAAAAAAAAQc/_8mNJy60qU8/s320/Clipboard01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_z6epD0KXWVs/TUsWxH8O9ZI/AAAAAAAAAQg/zzIxqCqmaPs/s1600/Clipboard02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="246" src="http://2.bp.blogspot.com/_z6epD0KXWVs/TUsWxH8O9ZI/AAAAAAAAAQg/zzIxqCqmaPs/s320/Clipboard02.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_z6epD0KXWVs/TUsWxou2gqI/AAAAAAAAAQk/XJNN0qH5yvo/s1600/Clipboard03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="246" src="http://2.bp.blogspot.com/_z6epD0KXWVs/TUsWxou2gqI/AAAAAAAAAQk/XJNN0qH5yvo/s320/Clipboard03.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-2796130644831133030?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/2796130644831133030/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/helper-ajax-com-jquery-ahan.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/2796130644831133030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/2796130644831133030'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/helper-ajax-com-jquery-ahan.html' title='Helper Ajax com jQuery, ahan!'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z6epD0KXWVs/TUsWwjhr1wI/AAAAAAAAAQc/_8mNJy60qU8/s72-c/Clipboard01.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-333778543502809100</id><published>2011-02-02T18:33:00.004-03:00</published><updated>2011-04-04T10:54:02.111-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='helper ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>Select combo (estado + cidade) usando o Helper Ajax (observeField)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_z6epD0KXWVs/TUsXOaTIYzI/AAAAAAAAAQo/hk2N4p8gwFw/s1600/title.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_z6epD0KXWVs/TUsXOaTIYzI/AAAAAAAAAQo/hk2N4p8gwFw/s1600/title.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Estou começando a utilizar o &lt;a href="http://book.cakephp.org/pt/view/1358/AJAX"&gt;Helper Ajax&lt;/a&gt; do CakePHP (baixei a versão 1.3.7), que utiliza o Prototype (e o Scriptaculous). Antes eu usava o jQuery para lidar com AJAX no Cake, mas conversando com o Ananias no &lt;a href="mailto:cakephp-pt@googlegroups.com"&gt;grupo&lt;/a&gt; resolvi implementar alguns métodos do Helper Ajax para conhecer melhor e para testar a sua performance.&lt;br /&gt;&lt;br /&gt;Bom, neste post pretendo mostrar uma forma de implementar aquele velho &lt;b&gt;select combo &lt;/b&gt;de "estado" e "cidade" (ou pais, estado e cidade), onde ao selecionar um determinado "estado" as "cidades" referentes a ele são carregadas no &lt;b&gt;select &lt;/b&gt;abaixo. Veja como fica simples de implementar usando o Helper Ajax.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1º) Eu criei duas tabelas: "estados" e "cidades" e criei também os respectivos: Models, Controllers e Views para elas. O código para criação das tabelas é:&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: sql"&gt;CREATE TABLE `estados` (&lt;br /&gt;  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;  `estado` varchar(255) NOT NULL,&lt;br /&gt;  PRIMARY KEY (`id`)&lt;br /&gt;) ENGINE=MyISAM  DEFAULT CHARSET=utf8;&lt;br /&gt;&lt;br /&gt;CREATE TABLE `cidades` (&lt;br /&gt;  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;  `estado_id` int(11) NOT NULL,&lt;br /&gt;  `cidade` varchar(255) NOT NULL,&lt;br /&gt;  PRIMARY KEY (`id`)&lt;br /&gt;) ENGINE=MyISAM  DEFAULT CHARSET=utf8;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;para gerar o MVC usei o &lt;a href="http://www.webdevelopment2.com/cakephp-bake-baking-models-controllers-views-cakephp-12/"&gt;BAKE&lt;/a&gt;.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2º) Criei também a tabela "users" e seu MVC usando o bake. Veja o SQL para criação da tabela:&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: sql"&gt;CREATE TABLE `users` (&lt;br /&gt;  `id` int(11) NOT NULL AUTO_INCREMENT,&lt;br /&gt;  `username` varchar(255) NOT NULL,&lt;br /&gt;  `password` char(40) NOT NULL,&lt;br /&gt;  `created` datetime DEFAULT NULL,&lt;br /&gt;  `modified` datetime DEFAULT NULL,&lt;br /&gt;  PRIMARY KEY (`id`),&lt;br /&gt;  UNIQUE KEY `username` (`username`)&lt;br /&gt;) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Criei o "users" apenas para servir como ponto de partida para o formulário onde serão carregados os dados de outros modelos (veja que o modelo "User" não possui relacionamento com "Estado" e nem com "Cidade", e nem vice-versa).&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3º) Bom, como tudo foi devidamente gerado via bake imagino que você já tenha todos os Models, Controllers e View devidamente criados (pelo menos o CRUD - add(), view(), delete() e edit()). &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4º) Em ..app/controllers/cidades_controller.php vamos criar a action "listar", veja:&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;function listar($estado_id = 1){&lt;br /&gt;  $this-&amp;gt;layout = 'ajax';&lt;br /&gt;  $this-&amp;gt;set('cidades', $this-&amp;gt;Cidade-&amp;gt;find('list', array(&lt;br /&gt;    'conditions' =&amp;gt; array(&lt;br /&gt;      'Cidade.estado_id' =&amp;gt; $estado_id      &lt;br /&gt;     ),&lt;br /&gt;    'fields' =&amp;gt; array(&lt;br /&gt;      'id', 'cidade'&lt;br /&gt;     ),&lt;br /&gt;   ))&lt;br /&gt;  );&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;e criar a view ...app/views/cidades/listar.ctp:&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;// Recebo $cidades&lt;br /&gt;echo '&amp;lt;option value=""&amp;gt;Selecione a cidade&amp;lt;/option&amp;gt;\n';&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;foreach($cidades as $id =&amp;gt; $cidade)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;echo "&amp;lt;option value='$id'&amp;gt;$cidade&amp;lt;/option&amp;gt;\n";&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;?&amp;gt;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Veja que essa view irá gerar as opções de cidades do nosso select Cidades.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;5º) No ...app/controllers/users_controllers.php vamos: definir a var $helpers, criar a action "listar_cidades" e modificar a action add:&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;class UsersController extends AppController {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var $name = 'Users';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var $helpers = array('Ajax', 'Javascript');&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function add() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (!empty($this-&amp;gt;data)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;User-&amp;gt;create();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if ($this-&amp;gt;User-&amp;gt;save($this-&amp;gt;data)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;Session-&amp;gt;setFlash(__('The user has been saved', true));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;redirect(array('action' =&amp;gt; 'index'));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;Session-&amp;gt;setFlash(__('The user could not be saved. Please, try again.', true));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Se o usuário selecionou algum estado, carregamos a lista de cidades para a view&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(!empty($this-&amp;gt;data['User']['estado'])){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;loadModel('Cidade');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $cidades = $this-&amp;gt;Cidade-&amp;gt;find('list', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'conditions' =&amp;gt; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'Cidade.estado_id' =&amp;gt; $this-&amp;gt;data['User']['estado']&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'fields' =&amp;gt; array('id', 'cidade'))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $cidades = array('' =&amp;gt; 'Selecione a cidade', $cidades);&amp;nbsp;&amp;nbsp;&amp;nbsp; // Adiciono o "Selecione a cidade" na lista de cidades&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;set('cidades', $cidades);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;loadModel('Estado');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $estados = $this-&amp;gt;Estado-&amp;gt;find('list', array('fields' =&amp;gt; array('id', 'estado')));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;set('estados', $estados);&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function listar_cidades(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Se foi informado o Estado via POST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(!empty($this-&amp;gt;data['User']['estado'])){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;redirect(array('controller' =&amp;gt; 'cidades', 'action' =&amp;gt; 'listar', $this-&amp;gt;data['User']['estado']));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;&amp;nbsp;Veja o código do formulário criado no view add, em ...app/views/users/add.ctp:&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&amp;nbsp;&lt;br /&gt;// Carrego o Prototype e o Scriptaculos&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js', false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $javascript-&amp;gt;link('https://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', false); &lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;div class="users form"&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;create('User');?&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;fieldset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;legend&amp;gt;&amp;lt;?php __('Add User'); ?&amp;gt;&amp;lt;/legend&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Form-&amp;gt;input('estado', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'options' =&amp;gt; $estados, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'empty' =&amp;gt; 'Selecione o estado'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&amp;nbsp;&lt;br /&gt;// Crio um Loading... para que o usuário saiba o que está ocorrendo&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo '&amp;lt;div id="loading" style="display: none"&amp;gt;&amp;lt;b&amp;gt;' . $html-&amp;gt;image('carregando.gif') . ' Aguarde, carregando cidades...&amp;lt;/b&amp;gt;&amp;lt;/div&amp;gt;';&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Form-&amp;gt;input('cidade', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'type' =&amp;gt; 'select',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Form-&amp;gt;input('username');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; echo $this-&amp;gt;Form-&amp;gt;input('password');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ?&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/fieldset&amp;gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;Form-&amp;gt;end(__('Submit', true));?&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div class="actions"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h3&amp;gt;&amp;lt;?php __('Actions'); ?&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&amp;lt;?php echo $this-&amp;gt;Html-&amp;gt;link(__('List Users', true), array('action' =&amp;gt; 'index'));?&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo $ajax-&amp;gt;observeField('UserEstado', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'url' =&amp;gt; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'action' =&amp;gt; 'listar_cidades' &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'frequency' =&amp;gt; 0.2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'update' =&amp;gt; 'UserCidade',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'indicator' =&amp;gt; 'loading',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ); &lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Bom. o resultado final é este!&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Imagem 1 - O Form com o select Estado com os valores do banco e o select Cidade vazio, aguardando a seleção do estado.:&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_z6epD0KXWVs/TUnMcoAhhyI/AAAAAAAAAQM/iV7rc1xB374/s1600/Clipboard02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="285" src="http://3.bp.blogspot.com/_z6epD0KXWVs/TUnMcoAhhyI/AAAAAAAAAQM/iV7rc1xB374/s320/Clipboard02.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Imagem 2 - O usuário seleciona um estado:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_z6epD0KXWVs/TUnMdYsnwFI/AAAAAAAAAQQ/k74Fo8ghwKU/s1600/Clipboard04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_z6epD0KXWVs/TUnMdYsnwFI/AAAAAAAAAQQ/k74Fo8ghwKU/s320/Clipboard04.jpg" width="318" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;Imagem 3 - Selecionado o estado a mensagem de carregando (atributo "indicator" do observeField()) aparece:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_z6epD0KXWVs/TUnMeMSGJKI/AAAAAAAAAQU/q54jjaGFJ-M/s1600/Clipboard06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="308" src="http://1.bp.blogspot.com/_z6epD0KXWVs/TUnMeMSGJKI/AAAAAAAAAQU/q54jjaGFJ-M/s320/Clipboard06.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;Imagem 4 - É carregada a lista de cidades!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_z6epD0KXWVs/TUnMenodt8I/AAAAAAAAAQY/iJzH94YKx18/s1600/Clipboard08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="306" src="http://2.bp.blogspot.com/_z6epD0KXWVs/TUnMenodt8I/AAAAAAAAAQY/iJzH94YKx18/s320/Clipboard08.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Espero que o artigo seja útil! Caso fique com alguma dúvida ou tenha uma sugestão/crítica, fique a vontade para comentar! =]&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-333778543502809100?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/333778543502809100/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/select-combo-estado-cidade-usando-o.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/333778543502809100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/333778543502809100'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/02/select-combo-estado-cidade-usando-o.html' title='Select combo (estado + cidade) usando o Helper Ajax (observeField)'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z6epD0KXWVs/TUsXOaTIYzI/AAAAAAAAAQo/hk2N4p8gwFw/s72-c/title.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-1491495594114437410</id><published>2011-01-21T18:47:00.002-03:00</published><updated>2011-01-21T18:54:33.733-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='cakebook'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>Expressões Regulares, um dia você precisará delas....</title><content type='html'>Opa... Eu sempre menosprezei as expressões regulares sem entender o poder delas. Elas não servem apenas para a validação de dados, como eu achava, pois com poucas coisa você consegue realizar pesquisas/verificações complexas.&lt;br /&gt;&lt;br /&gt;Uma expressão regular é um padrão formado por simples caracteres alfa-numéricos e especiais.Ou seja, a expressão: &lt;code&gt;/[aeiou]/gi&lt;/code&gt;, encontraria todas as vogais maiúsculas ou minúsculas em um determinado texto.&lt;br /&gt;&lt;br /&gt;Para saber mais sobre a sintaxe eu recomendo a leitura deste artigo do iMasters, &lt;a target="_blank" href="http://imasters.com.br/artigo/2515/javascript/regular_expression/"&gt;http://imasters.com.br/artigo/2515/javascript/regular_expression/&lt;/a&gt;, entre outros que você encontra facilmente no Google. E se quiser "treinar" os seus conhecimentos poderá utilizar o &lt;a target="_blank" href="http://gskinner.com/RegExr/"&gt;http://gskinner.com/RegExr/&lt;/a&gt; para testar seus padrões. &lt;br /&gt;&lt;br /&gt;Mas o que isso tem haver com o CakePHP? Tem muito! Não só com o Cake, mas todo programador que se preze deve conhecer o básico de expressões regulares, pois ela poupa um precioso tempo. Veja um exemplo básico de como usar expressões regulares no Cake:&lt;br /&gt;&lt;br /&gt;O &lt;code&gt;$validate&lt;/code&gt; aceita &lt;b&gt;&lt;a target="_blank" href="http://book.cakephp.org/pt/view/1179/Regras-de-Valida%C3%A7%C3%A3o-Customizadas"&gt;regras de validação customizadas&lt;/a&gt;&lt;/b&gt; onde podemos utilizar: expressões regulares ou métodos (funções). No próprio book do Cake ele dá o exemplo abaixo:&lt;br /&gt;&lt;pre class="brush: php"&gt;var $validate = array(&lt;br /&gt;    'login' =&amp;gt; array(&lt;br /&gt;        'rule' =&amp;gt; array('custom', '/[a-z0-9]{3,}$/i'),  &lt;br /&gt;        'message' =&amp;gt; 'Apenas letras e números, mínimo de 3 caracteres'&lt;br /&gt;    )&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pensando assim já podemos imaginar infinitas possibilidades de validação resolvidas com as benditas Regular Expressions.&lt;br /&gt;&lt;br /&gt;Por hoje é só, flws&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-1491495594114437410?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/1491495594114437410/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2011/01/expressoes-regulares-um-dia-voce.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1491495594114437410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1491495594114437410'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2011/01/expressoes-regulares-um-dia-voce.html' title='Expressões Regulares, um dia você precisará delas....'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-5270313108399180672</id><published>2010-06-28T15:55:00.009-04:00</published><updated>2011-01-17T17:34:48.098-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='jqueryui'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='autocomplete'/><title type='text'>jQueryUI Autocomplete no CakePHP - Agora sim!</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_z6epD0KXWVs/TCkT3fVIh2I/AAAAAAAAAPY/G2LYbYCCRkQ/s1600/autocomplete.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5487939464951531362" src="http://1.bp.blogspot.com/_z6epD0KXWVs/TCkT3fVIh2I/AAAAAAAAAPY/G2LYbYCCRkQ/s400/autocomplete.jpg" style="cursor: pointer; float: left; height: 182px; margin: 0pt 10px 10px 0pt; width: 400px;" /&gt;&lt;/a&gt;Dias atrás postei como usar o &lt;a href="http://jqueryui.com/demos/autocomplete"&gt;Autocomplete do jQueryUI&lt;/a&gt; no cakePHP, porém tive que fazer uma "gambiarra" pra que a opção de obter os valores via data source "funcionasse".&lt;br /&gt;&lt;br /&gt;Bom, então depois de um help do pessoal do &lt;a href="http://groups.google.com/group/jquery-br?hl=pt-BR"&gt;jquery-br&lt;/a&gt; vi que o arquivo que gera os resultados recebe um valor via GET através da variável "term". Com isso basta verificar quais das chaves possui o "term" (ou até aqueles que começam com "term", basta algumas alterações no código).&lt;br /&gt;&lt;br /&gt;Agora veja a solução pronta!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1º O Controller Users (./app/controllers/users_controller.php):&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php" name="code"&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* @author Carlitos Fioravante&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;class UsersController extends AppController {&lt;br /&gt;  var $name = 'Users';&lt;br /&gt;  var $helpers = array('Javascript');&lt;br /&gt;&lt;br /&gt;  function autocomplete(){&lt;br /&gt;    $this-&amp;gt;set('users', $this-&amp;gt;User-&amp;gt;find('list', array('fields' =&amp;gt; 'User.username')));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function list_users(){&lt;br /&gt;    $this-&amp;gt;layout = false;&lt;br /&gt;    $this-&amp;gt;set('users', $this-&amp;gt;User-&amp;gt;find('list', array('fields' =&amp;gt; 'User.username')));&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;2º A view "autocomplete.ctp" (./app/views/users/autocomplete.ctp):&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php" name="code"&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* @author Carlitos Fioravante&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;$javascript-&amp;gt;link(array('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'), false);&lt;br /&gt;echo $html-&amp;gt;css('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/flick/jquery-ui.css', null, array('inline' =&amp;gt; false));&lt;br /&gt;&lt;br /&gt;$javascript-&amp;gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;    $("#username").autocomplete({&lt;br /&gt;      source: "' . $html-&amp;gt;url(array('action' =&amp;gt; 'list_users')) . '"&lt;br /&gt;    });&lt;br /&gt;  });&lt;br /&gt;', array('inline' =&amp;gt; false));&lt;br /&gt;&lt;br /&gt;echo $form-&amp;gt;create('Users');&lt;br /&gt;echo $form-&amp;gt;input('username', array('id' =&amp;gt; 'username'));&lt;br /&gt;echo $form-&amp;gt;end('OK');&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;3º A view "list_users.ctp"  (./app/views/users/list_users.ctp):&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: php" name="code"&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* @author Carlitos Fioravante&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;header('Content-type: application/json; charset=UTF-8');&lt;br /&gt;&lt;br /&gt;$users_selecteds = array();&lt;br /&gt;&lt;br /&gt;if(!empty($_GET['term'])){&lt;br /&gt;  foreach($users as $user){&lt;br /&gt;    if(strripos($user, $_GET['term']) !== false){&lt;br /&gt;      array_push($users_selecteds, $user);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo json_encode($users_selecteds);&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Táh aê! Espero que seja proveitoso para alguém!&lt;br /&gt;&lt;br /&gt;Abraço,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-5270313108399180672?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/5270313108399180672/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html#comment-form' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/5270313108399180672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/5270313108399180672'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html' title='jQueryUI Autocomplete no CakePHP - Agora sim!'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z6epD0KXWVs/TCkT3fVIh2I/AAAAAAAAAPY/G2LYbYCCRkQ/s72-c/autocomplete.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-8696562465998747501</id><published>2010-06-22T15:08:00.011-04:00</published><updated>2011-01-17T17:43:27.174-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='jqueryui'/><category scheme='http://www.blogger.com/atom/ns#' term='autocomplete'/><title type='text'>jQueryUI Autocomplete no CakePHP</title><content type='html'>Então... um colega nosso do grupo cakephp-br entrou em contato comigo via MP perguntando como utilizar o &lt;a href="http://jqueryui.com/demos/autocomplete/"&gt;autocomplete do jQueryUI&lt;/a&gt; no CakePHP. Topei ajudá-lo e já aproveitei para conhecer as novidades do Cake 1.3.2.&lt;br /&gt;&lt;br /&gt;Bom, depois de quebrar um pouco a cabeça com as mudanças na forma de invocar o JavaScript, entre outras mudanças neste novo cake, cheguei a uma solução que eu não recomendo para o caso em que o campo a ser listado do BD tenha muitos registros. E pensando bem um campo autocomplete é sempre mais indicado nestas circunstâncias mesmo, por exemplo para autocompletar um nome de um produto (de uma lista já predefinida, normalmente não muito grande), de uma cidade, etc.&lt;br /&gt;&lt;br /&gt;Primeiramente vamos ver o que o jQueryUI diz a respeito do Autocomplete.&lt;br /&gt;&lt;br /&gt;1) Na opção "default" o Autocomplete pode ser gerado a partir de uma lista de "tags" pré-definidas em um Array passado à variável "source" da função, assim:&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;$(function() {&lt;br /&gt;  var availableTags = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"];&lt;br /&gt;  $("#tags").autocomplete({&lt;br /&gt;    source: availableTags&lt;br /&gt;  });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2) Outra opção é obter este Array de tags através de uma página que retorne um array no formato JSON, assim:&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;$(function() {&lt;br /&gt;  $("#tags").autocomplete({&lt;br /&gt;    source: "search.php"&lt;br /&gt;  });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Como os dados estão numa tabela do BD o ideal seria usar a 2ª opção, porém não consegui utilizá-la. Criei uma página que gerava o array no formato JSON (Ex.: ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"]), porém o autocomplete "puxava" todos os elementos como se fossem um só, ou seja, se eu começava a digitar "a" ele me mostrava todas as opções do Array e não apenas aquelas que continham o caractere "a".&lt;br /&gt;&lt;br /&gt;Bom, parti para a 1ª opção então. Dentro do meu controller eu criei a action "autocomplete" e nela eu busco todos os registros que quero para o meu campo "autocompletável" :D, assim:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;function autocomplete(){&lt;br /&gt;  $this-&gt;set('users', $this-&gt;User-&gt;find('list', array('fields' =&gt; 'User.username')));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Obs.: No meu caso estou usando uma tabela "Users" que possui um campo "username".&lt;br /&gt;&lt;br /&gt;Já na view "autocomplete.ctp" eu estou recebendo a variável $users, que vem com um Array da seguinte forma:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;Array&lt;br /&gt;(&lt;br /&gt;  [1] =&gt; a1_teste@teste.com&lt;br /&gt;  [2] =&gt; a2_teste@teste.com&lt;br /&gt;  [3] =&gt; outro_nome_de_teste@teste.com&lt;br /&gt;   .&lt;br /&gt;   .&lt;br /&gt;   .&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;e então crio uma String com o formato array do JSON, desta forma:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;$usernames = '[';&lt;br /&gt;&lt;br /&gt;foreach($users as $user)&lt;br /&gt;  $usernames .= '"' . $user . '",';&lt;br /&gt;&lt;br /&gt;$usernames .= ']';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Então temos o seguinte código para a view:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* @author Carlitos Fioravante&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;$javascript-&gt;link(array('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'), false);&lt;br /&gt;echo $html-&gt;css('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/flick/jquery-ui.css', null, array('inline' =&gt; false)); // Tema do Flickr, hehe :D&lt;br /&gt;&lt;br /&gt;$usernames = '[';&lt;br /&gt;&lt;br /&gt;foreach($users as $user)&lt;br /&gt;  $usernames .= '"' . $user . '",';&lt;br /&gt;&lt;br /&gt;$usernames .= ']';&lt;br /&gt;&lt;br /&gt;$javascript-&gt;codeBlock('&lt;br /&gt;  jQuery(function($){&lt;br /&gt;    var usernames = ' . $usernames . ';&lt;br /&gt;    $("#username").autocomplete({&lt;br /&gt;      source: usernames&lt;br /&gt;    });&lt;br /&gt;  });&lt;br /&gt;', array('inline' =&gt; false));&lt;br /&gt;&lt;br /&gt;echo $form-&gt;create('Users');&lt;br /&gt;echo $form-&gt;input('username', array('id' =&gt; 'username'));&lt;br /&gt;echo $form-&gt;end('OK');&lt;br /&gt;&lt;br /&gt;debug($users);&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;s&gt;Bom, não é a solução perfeita mas funcionou! Ainda estou a procura dela...&lt;/s&gt;&lt;br /&gt;&lt;br /&gt;Veja a solução correta &lt;a href="http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp-agora.html"&gt;aqui&lt;/a&gt; nesse novo post!&lt;br /&gt;&lt;br /&gt;Abraço,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-8696562465998747501?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/8696562465998747501/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/8696562465998747501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/8696562465998747501'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/06/jqueryui-autocomplete-no-cakephp.html' title='jQueryUI Autocomplete no CakePHP'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-7336828740056913884</id><published>2010-02-18T21:01:00.002-03:00</published><updated>2010-02-18T21:04:17.087-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='logo'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Até que enfim uma logo!</title><content type='html'>Logo nova (quer dizer... primeira logo) e postagem nova que é bom nada! Hehe!&lt;br /&gt;Em breve trago novidades, estou estudando a API do Google Maps, que é fantástica e dá pra fazer um monte de coisa legal rapidinho. Assim que tiver algo realmente legal, posto aqui!&lt;br /&gt;&lt;br /&gt;Flws!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-7336828740056913884?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/7336828740056913884/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/02/ate-que-enfim-uma-logo.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/7336828740056913884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/7336828740056913884'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/02/ate-que-enfim-uma-logo.html' title='Até que enfim uma logo!'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-4939291684129075726</id><published>2010-01-19T18:35:00.001-03:00</published><updated>2011-01-17T17:49:06.821-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='vendor'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='bakery'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><title type='text'>Captcha usando o vendor PhpCaptcha</title><content type='html'>Bom, alguns dias sem postar nada e eu procurando algo interessante para compartilhar com vocês. Vamos lá então...&lt;br /&gt;&lt;br /&gt;Estava quebrando a cabeça para implementar um Captcha (Isso mesmo! CAPTCHA, ou seja, aquelas letrinhas todas bagunçadas que impedem que um "não-humano" consiga submeter um formulário automaticamente... se bem que as vezes até um humano não consegue identificar as letras, mas vamos lá).&lt;br /&gt;&lt;br /&gt;Baseado neste artigo que vi no Bakery vamos utilizar o PhpCaptcha como vendor. Segue os passos:&lt;br /&gt;&lt;br /&gt;1) Faça o download do PhpCaptcha através do link &lt;a href="http://www.ejeliot.com/pages/2"&gt;http://www.ejeliot.com/pages/2&lt;/a&gt; e descompacte o arquivo em "app/vendors/phpcaptcha" (crie este diretório caso não exista).&lt;br /&gt;&lt;br /&gt;2) Faça o download dos arquivos de fontes Vera do GNOME através do link &lt;a href="http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.zip"&gt;http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.zip&lt;/a&gt; e descompacte o arquivo em  "app/vendors/phpcaptcha/fonts/".&lt;br /&gt;&lt;br /&gt;3) Vamos criar o componente Captcha:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;// Salve em app/controllers/componentes/captcha.php&lt;br /&gt;&lt;br /&gt;App::import('Vendor','PhpCaptcha' ,array('file'=&gt;'phpcaptcha'.DS.'php-captcha.inc.php'));&lt;br /&gt;&lt;br /&gt;class CaptchaComponent extends Object&lt;br /&gt;{&lt;br /&gt;  var $controller;&lt;br /&gt;&lt;br /&gt;  function startup( &amp;amp;$controller ) {&lt;br /&gt;    $this-&gt;controller = &amp;amp;$controller;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function image(){&lt;br /&gt;&lt;br /&gt;    $imagesPath = APP . 'vendors' . DS . 'phpcaptcha'.'/fonts/';&lt;br /&gt;&lt;br /&gt;    $aFonts = array(&lt;br /&gt;      $imagesPath.'VeraBd.ttf',&lt;br /&gt;      $imagesPath.'VeraIt.ttf',&lt;br /&gt;      $imagesPath.'Vera.ttf'&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;    $oVisualCaptcha = new PhpCaptcha($aFonts, 200, 60);&lt;br /&gt;&lt;br /&gt;    $oVisualCaptcha-&gt;UseColour(true);&lt;br /&gt;    //$oVisualCaptcha-&gt;SetOwnerText('Source: '.FULL_BASE_URL);&lt;br /&gt;    //$oVisualCaptcha-&gt;SetNumChars(6);&lt;br /&gt;    $oVisualCaptcha-&gt;Create();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function audio(){&lt;br /&gt;    $oAudioCaptcha = new AudioPhpCaptcha('/usr/bin/flite', '/tmp/');&lt;br /&gt;    $oAudioCaptcha-&gt;Create();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function check($userCode, $caseInsensitive = true){&lt;br /&gt;    if ($caseInsensitive) {&lt;br /&gt;      $userCode = strtoupper($userCode);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (!empty($_SESSION[CAPTCHA_SESSION_ID]) &amp;amp;&amp;amp; $userCode == $_SESSION[CAPTCHA_SESSION_ID]) {&lt;br /&gt;      // clear to prevent re-use&lt;br /&gt;      unset($_SESSION[CAPTCHA_SESSION_ID]);&lt;br /&gt;&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4) Adicione os métodos aos controllers que desejar. No caso vou adicionar ao controller Users:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;class UsersController extends AppController&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;  // Adicione o componente Captcha ao controller&lt;br /&gt;  var $components = array('Captcha');&lt;br /&gt;  ...&lt;br /&gt;  function captcha_image(){&lt;br /&gt;    Configure::write('debug',0);&lt;br /&gt;    $this-&gt;layout = null;&lt;br /&gt;    $this-&gt;Captcha-&gt;image();&lt;br /&gt;    $this-&gt;render();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Não vou entrar no mérito do captcha com audio&lt;br /&gt;  function captcha_audio()&lt;br /&gt;  {&lt;br /&gt;    $this-&gt;Captcha-&gt;audio();&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5) Na view invoque o método captcha_image:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;&amp;lt;img id="captcha" src="&amp;lt;?php echo $html-&gt;url('/users/captcha_image'); ?&amp;gt;" alt="" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;6) Agora para verificar se o usuário digitou corretamente os caracteres do Captcha usamos a função check, veja:&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;// Suponha que o campo texto onde o usuário preencheu os caracteres que leu&lt;br /&gt;// no captcha seja "captcha", então temos&lt;br /&gt;if(!$this-&gt;Captcha-&gt;check($this-&gt;data['User']['captcha'])){&lt;br /&gt;  $this-&gt;Session-&gt;setFlash('Você não preencheu corretamente as letras da imagem!');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Veja como fica o resultado deste captcha colorido:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z6epD0KXWVs/S1Ysw8OBK8I/AAAAAAAAALw/TyuB6W8nYsI/s1600-h/captcha.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 50px;" src="http://1.bp.blogspot.com/_z6epD0KXWVs/S1Ysw8OBK8I/AAAAAAAAALw/TyuB6W8nYsI/s320/captcha.jpg" alt="" id="BLOGGER_PHOTO_ID_5428575620151978946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Bom, espero que funcione, pois aqui funcionou. Tem outros captchas para Cake e PHP também, veja &lt;a href="http://www.exuber.net/2008/05/06/cakephp-captcha-and-user-registration/"&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Abração!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-4939291684129075726?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/4939291684129075726/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/captcha-usando-o-vendor-phpcaptcha.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/4939291684129075726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/4939291684129075726'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/captcha-usando-o-vendor-phpcaptcha.html' title='Captcha usando o vendor PhpCaptcha'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z6epD0KXWVs/S1Ysw8OBK8I/AAAAAAAAALw/TyuB6W8nYsI/s72-c/captcha.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-8362761657747630924</id><published>2010-01-13T19:23:00.001-03:00</published><updated>2010-01-13T19:33:05.084-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='exportar dados'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='bakery'/><title type='text'>Exportar dados - O príncipio...</title><content type='html'>Bom, sempre é preciso exportar dados (se vc ainda não fez isso, certamente num futuro próximo fará :P).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Missão:&lt;/span&gt;  implementar um exportação de dados (para formatos: .xls - Excel, .doc - Word e .pdf, Adobe Reader)  usando o CakePHP.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Colhendo dados:&lt;/span&gt; achei uma solução pronta para o .xls no Bakery - &lt;a href="http://bakery.cakephp.org/articles/view/generate-excel-spreadsheets-from-your-database"&gt;http://bakery.cakephp.org/articles/view/generate-excel-spreadsheets-from-your-database&lt;/a&gt;, li por cima mas não implementei. Achei também outra solução no &lt;a href="http://codigofonte.uol.com.br/codigo/php/arquivos/exportar-para-excel-os-dados-de-uma-tabela-mysql"&gt;CodigoFonte do UOL&lt;/a&gt; para implementar o .xls, essa eu testei e funcionou, falta apenas adicionar ao Cake pois esta em php simples. E achei também, &lt;a href="http://www.rodrigoregis.com.br/2009/07/exportar-para-word-com-php/"&gt;neste blog aqui&lt;/a&gt;, uma implementação para .doc e para .xls, mas não testei ainda. Para o PDF usei uma solução pronta do Bakery usando o FPDF.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cenas do próximo capítulo:&lt;/span&gt; Testar os scripts e ver qual possui o melhor desempenho. Verificar qual a melhor forma de acopla-los ao Cake (se via Helper ou Component).&lt;br /&gt;&lt;br /&gt;Abraço,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-8362761657747630924?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/8362761657747630924/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/exportar-dados-o-principio.html#comment-form' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/8362761657747630924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/8362761657747630924'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/exportar-dados-o-principio.html' title='Exportar dados - O príncipio...'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-1151063622458000090</id><published>2010-01-12T12:03:00.001-03:00</published><updated>2011-01-17T17:53:21.933-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='cakebook'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='componentes'/><title type='text'>Criando componentes</title><content type='html'>Bom dia povo! Ontem eu vi que havia um trecho de código que sempre se repetia ao longo de alguns controllers de um sistema em Cake que estou desenvolvendo e resolvi criar um componente com esta funcionalidade e aproveitar o reuso de código de forma limpa né ;)&lt;br /&gt;&lt;br /&gt;Bom, vamos lá... mãos a obra!&lt;br /&gt;&lt;br /&gt;O código é simples, trata-se de uma função que retorna o nome do navegador (browser) que o usuário está utilizando e qual a versão dele. Mas pra que usar isto, mano? Bom, é muito útil quando há alguma parte do seu site/sistema que "não funciona" em determinado navegador. Por exemplo, no meu caso existe uns getgads (firulas) na parte de validação de formulário que "não funciona" no IE 6 ou inferior.&lt;br /&gt;&lt;br /&gt;Os componentes devem ficar dentro da pasta "./app/controllers/components/". O nome do meu componente é "Navegador", então criei o arquivo "./app/controllers/components/navegador.php", com o código&lt;br /&gt;&lt;pre name='code' class='brush: php'&gt;&amp;lt;?php&lt;br /&gt;class NavegadorComponent extends Object {&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Depois adicionei a função que retorna as informações sobre o navegador&lt;br /&gt;&lt;pre name='code' class='brush: php'&gt;&amp;lt;?php&lt;br /&gt;class NavegadorComponent extends Object {&lt;br /&gt;  // Função que retorna o Brownser que está sendo usado&lt;br /&gt;  function getBrowser(){&lt;br /&gt;    $var = $_SERVER['HTTP_USER_AGENT'];&lt;br /&gt;    $info['browser'] = "OTHER";&lt;br /&gt;    // valid brosers array&lt;br /&gt;    $browser = array ("MSIE", "OPERA", "FIREFOX", "MOZILLA", "NETSCAPE", "SAFARI", "LYNX", "KONQUEROR");&lt;br /&gt;    // bots = ignore&lt;br /&gt;    $bots = array('GOOGLEBOT', 'MSNBOT', 'SLURP');&lt;br /&gt;&lt;br /&gt;    foreach ($bots as $bot)&lt;br /&gt;    // if bot, returns OTHER&lt;br /&gt;    if (strpos(strtoupper($var), $bot) !== FALSE)&lt;br /&gt;      return $info;&lt;br /&gt;&lt;br /&gt;    // loop the valid browsers&lt;br /&gt;    foreach ($browser as $parent){&lt;br /&gt;      $s = strpos(strtoupper($var), $parent);&lt;br /&gt;      $f = $s + strlen($parent);&lt;br /&gt;      $version = substr($var, $f, 5);&lt;br /&gt;      $version = preg_replace('/[^0-9,.]/','',$version);&lt;br /&gt;      if (strpos(strtoupper($var), $parent) !== FALSE){&lt;br /&gt;        $info['browser'] = $parent;&lt;br /&gt;        $info['version'] = $version;&lt;br /&gt;        return $info;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return $info;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Agora para poder ter acesso a esta nova funcionalidade você deverá adicionar o componente "Navegador" ao seu controller. Mas como? Veja exemplo abaixo&lt;br /&gt;&lt;pre name='code' class='brush: php'&gt;&amp;lt;?php&lt;br /&gt;class TestesController extends AppController{&lt;br /&gt;  $components = array('Navegador'); // Adiciono o componente "Navegador" ao  controller Testes&lt;br /&gt;&lt;br /&gt;  function add(){&lt;br /&gt;    /* guardo na variável 'browser' o array retornado pela função getBrowser do&lt;br /&gt;    * meu componente Navegador com os dados do navegador do usuário &lt;br /&gt;    * como usei o $this-&gt;set, esta informação estará disponível para a view add&lt;br /&gt;    * através da variável $browser, que é um array. */&lt;br /&gt;&lt;br /&gt;    $this-&gt;set('browser', $this-&gt;Navegador-&gt;getBrowser());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Simples não? Espero que tenham entendido e que seja útil!&lt;br /&gt;Consultem também a documentação oficial do CakePHP sobre o uso e criação de componentes &lt;a href="http://book.cakephp.org/pt/view/64/Creating-Components"&gt;aqui&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Abração,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-1151063622458000090?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/1151063622458000090/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/criando-componentes.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1151063622458000090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1151063622458000090'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/criando-componentes.html' title='Criando componentes'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-7120536746180506289</id><published>2010-01-09T18:10:00.001-03:00</published><updated>2011-01-17T17:56:22.861-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><title type='text'>Adicionar Syntax Highlight ao layout do Blogger/Blogspot</title><content type='html'>É muito ruim ler um código sem &lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Syntax_highlight"&gt;syntax highlight&lt;/a&gt;, não é? Pois é, passei alguns duas postando aqui no cakenaveia e resolvi procurar esse recurso para adicionar ao bloguezito... achei um muito legal que atende a diversas linguagens: PHP, HTML, CSS, JScript, Java, Perl e etc. O projeto é velhinho já (desde 2007) e muito bacana, veja &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;aqui no site do script deles&lt;/a&gt; (mas só fiquei sabendo deles através do artigo deste camarada &lt;a href="http://abhisanoujam.blogspot.com/2008/12/blogger-syntax-highlighting.html"&gt;aqui&lt;/a&gt; {créditos}.&lt;br /&gt;&lt;br /&gt;Então mãos a obra:&lt;br /&gt;1º) baixe os scripts &lt;a href="http://syntaxhighlighter.googlecode.com/files/SyntaxHighlighter_1.5.1.rar"&gt;aqui&lt;/a&gt;, em seguida hospede eles em algum lugar.&lt;br /&gt;2º) Acesse o painel de controle do seu blog (blogspot/blogger - mas vale para qualquer outro feito em Wordpress), vá até a aba &lt;span style="font-weight: bold;"&gt;Layout &lt;/span&gt;em seguida &lt;span style="font-weight: bold;"&gt;HTML&lt;/span&gt;.&lt;br /&gt;3º) Dentro do HEAD do html do blog adicione os scripts do syntaxhighlight das linguagens que você vai precisar, veja:&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;&lt;!-- Core --&gt;&lt;br /&gt;&amp;lt;script language='javascript' src='http://...seusite.../shCore.js'/&amp;gt;&lt;br /&gt;&lt;!-- Java --&gt;&lt;br /&gt;&amp;lt;script language='javascript' src='http://...seusite.../shBrushJava.js'/&amp;gt;&lt;br /&gt;&lt;!-- Php --&gt;&lt;br /&gt;&amp;lt;script language='javascript' src='http://...seusite.../shBrushPhp.js'/&amp;gt;&lt;br /&gt;&lt;!-- Javascript --&gt;&lt;br /&gt;&amp;lt;script language='javascript' src='http://...seusite.../shBrushJScript.js'/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Adicione também o CSS do syntaxhighlight&lt;br /&gt;&lt;pre name="code" class="brush: css"&gt;&amp;lt;link href='http://...seusite.../SyntaxHighlighter.css' rel='stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4º)Antes da &amp;lt;/body&amp;gt; adicione o código&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;&amp;lt;script language='javascript'&amp;gt;&lt;br /&gt;  dp.SyntaxHighlighter.ClipboardSwf = 'http://...seusite.../clipboard.swf';&lt;br /&gt;  dp.SyntaxHighlighter.BloggerMode();&lt;br /&gt;  dp.SyntaxHighlighter.HighlightAll('code');&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5º) Pronto! Agora para usar basta escrevesr os códigos dentro de um tag &amp;lt;pre name='code' class='php ou css ou html.. (a linguagem que vc está escrevendo)&amp;gt; seus codigos &amp;lt;pre&amp;gt; e eles aparecerão bonitinhos para os leitores.&lt;br /&gt;&lt;br /&gt;Abração pra todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-7120536746180506289?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/7120536746180506289/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/adicionar-syntax-highlight-ao-layout-do.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/7120536746180506289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/7120536746180506289'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/adicionar-syntax-highlight-ao-layout-do.html' title='Adicionar Syntax Highlight ao layout do Blogger/Blogspot'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-1655523484784437626</id><published>2010-01-08T13:54:00.004-03:00</published><updated>2011-01-17T18:05:04.818-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Mensagem carregando... usando CSS e Javascript</title><content type='html'>Corri atrás de uma forma simples de mostrar uma mensagem de "Carregando..." quando o usuário clica em um link e aguarda o processamento das informações. Bom, depois de muito camelar pela internet colhi algumas informações e fiz um bem simples usando o atributo FIXED do CSS. Mãos a obra!!!&lt;br /&gt;&lt;br /&gt;1º) Bom, primeiro adicionamos o script abaixo no head do layout default. No meu caso é o default.ctp.&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;//Mostra o carregador&lt;br /&gt;function __loadMostra(){&lt;br /&gt;  var objLoader = document.getElementById("carregador_pai");&lt;br /&gt;  objLoader.style.display = "block";&lt;br /&gt;  objLoader.style.visibility = "visible";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Este código "mostra" (atribui 'block' e 'visible' para ele) o elemento carregando.&lt;br /&gt;&lt;br /&gt;2º) Adicione a DIV que contém a mensagem de carregando.&lt;br /&gt;&lt;pre name="code" class="brush: html"&gt;&lt;div id="carregador_pai" style="display: none; visibility: hidden;"&gt; &lt;div id="carregador_posicao"&gt;  &lt;div id="carregador"&gt;   &lt;div style="line-height: 30px;" align="center"&gt;    &lt;strong&gt;Aguarde carregando ...&lt;/strong&gt;&lt;br /&gt;   &lt;/div&gt;   &lt;div align="center"&gt;imagem de carregando&lt;/div&gt;  &lt;/div&gt; &lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Observe que declarei que a DIV deve ficar escondida (display: none; visibility: hidden;).&lt;br /&gt;Como eu uso o CakePHP eu adicionei uma imagem (&lt;a href="http://www.ajaxload.info/"&gt;aqui neste site&lt;/a&gt; tem várias imagens de Carregando para escolher):&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;echo image('carregando.gif', array('alt' =&gt; 'Carregando...', 'border' =&gt; 0));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3º)Adicione o seguinte CSS:&lt;br /&gt;&lt;pre name="code" class="brush: css"&gt;#carregador_pai{&lt;br /&gt;  width: 100%;&lt;br /&gt;  height:100%;&lt;br /&gt;  position: absolute;&lt;br /&gt;  text-align: center;&lt;br /&gt;  background-color:#414141;&lt;br /&gt;  filter:alpha(opacity=90);&lt;br /&gt;  opacity:0.9;&lt;br /&gt;  overflow: auto;&lt;br /&gt;  top: 0;&lt;br /&gt;  left: 0;&lt;br /&gt;  z-index:2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#carregador_fundo{&lt;br /&gt;  font-size: 1px;&lt;br /&gt;  left: 8px;&lt;br /&gt;  width: 113px;&lt;br /&gt;  position: relative;&lt;br /&gt;  top: 50px;&lt;br /&gt;  height: 7px;&lt;br /&gt;  background-color: #ebebe4&lt;br /&gt;}&lt;br /&gt;#carregador_posicao{&lt;br /&gt;  padding-top:20%;&lt;br /&gt;}&lt;br /&gt;#carregador{&lt;br /&gt;  border-right: #6a6a6a 1px solid;&lt;br /&gt;  padding: 0px 10px 0px 16px;&lt;br /&gt;  border-top: #6a6a6a 1px solid;&lt;br /&gt;  display: block;&lt;br /&gt;  font-size: 11px;&lt;br /&gt;  z-index: 2;&lt;br /&gt;  margin: 0px auto;&lt;br /&gt;  border-left: #6a6a6a 1px solid;&lt;br /&gt;  width: 250px;&lt;br /&gt;  height:70px;&lt;br /&gt;  color: #000000;&lt;br /&gt;  border-bottom: #6a6a6a 1px solid;&lt;br /&gt;  font-family: Tahoma, Helvetica, sans;&lt;br /&gt;  background-color: #ffffff;&lt;br /&gt;  text-align: left;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@media screen{&lt;br /&gt;  body&gt;div#carregador_pai{&lt;br /&gt;    position: fixed;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Esse CSS cria uma tela como na imagem abaixo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_z6epD0KXWVs/S0eNsbTLZ3I/AAAAAAAAALo/8G4jy3LO4IA/s1600-h/Clipboard02.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 151px;" src="http://2.bp.blogspot.com/_z6epD0KXWVs/S0eNsbTLZ3I/AAAAAAAAALo/8G4jy3LO4IA/s320/Clipboard02.jpg" alt="" id="BLOGGER_PHOTO_ID_5424460070573008754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Ah! Esse CSS não funciona no IE¨6 ou inferior. Mas quem liga né? ;) Desde já estou fazendo minha parte no movimento ATUALIZE SEU IE! E outra coisa, o único problema que os usuários do Internet Explorer 6 ou inferior terão é que não verão a tela de Carregando, mas o carregamento da página não é afetado.&lt;br /&gt;&lt;br /&gt;4º) Guenta aí, tá quase acabando ;). Agora sempre que você tiver um link basta adicionar a função&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;onclick = "__loadMostra();";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ou seja, ao clicar ele mostra a DIV do Carregando... e assim que a próxima página termina de ser carregada a DIV volta a ser ocultada. Dá para adicionar ele nos formulário também, excluindo o botão de submit e criando um INPUT type BUTTON e adicionando o __loadMostra() seguido do submit().&lt;br /&gt;&lt;pre name="code" class="brush: jscript"&gt;onclick = "__loadMostra(); submit();";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Com o CakePHP fica assim&lt;br /&gt;&lt;pre name="code" class="brush: php"&gt;// Cria o botão de Enviar que submete o formulário&lt;br /&gt;echo $form-&gt;button('Enviar', array('onclick' =&gt; '__loadMostra(); submit();'));&lt;br /&gt;// Cria a tag /FORM&lt;br /&gt;echo $form-&gt;end();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Simples não? Dúvidas? Eu gostei do resultado final. Se tiver algo errado comentem aí!&lt;br /&gt;&lt;br /&gt;Ah! Na imagem parece que estou usando o IE8 né? Não... esse é o Firefox "camuflado" com o thema "ie8fox".&lt;br /&gt;&lt;br /&gt;Abração!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-1655523484784437626?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/1655523484784437626/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/mensagem-carregando-usando-css-e.html#comment-form' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1655523484784437626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/1655523484784437626'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/mensagem-carregando-usando-css-e.html' title='Mensagem carregando... usando CSS e Javascript'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_z6epD0KXWVs/S0eNsbTLZ3I/AAAAAAAAALo/8G4jy3LO4IA/s72-c/Clipboard02.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9151990965170112620.post-2562603755709941527</id><published>2010-01-07T18:43:00.001-03:00</published><updated>2011-01-17T18:06:25.403-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='cakebook'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='auth'/><title type='text'>Confirmação de senha</title><content type='html'>Poxa, havia criado um formulário para criação de um novo usuário com os campos: username, password e email. Hoje precisei implementar um novo campo (Repita a senha)... como uso o "Auth" sempre que há um array contendo as chaves "username" e "password" ele automágicamente (como dizem a galerinha do CakeBook) encriptografa o campo password usando as configurações de Salt definidas no core.php (Blz, mas isso não vem ao caso).&lt;br /&gt;&lt;br /&gt;Bom, o problema é que quando comparava&lt;pre name='code' class='brush: php'&gt;if($this-&gt;data['User']['password'] == $this-&gt;data['User']['confirm_password']) &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dava errado... depois de uns debugs no array $this-&gt;data percebi que o password já chegava ao controller encriptado, então a solução descobri &lt;a href="http://book.cakephp.org/pt/view/386/password"&gt;aqui&lt;/a&gt;. Basta usar o metódo $this-&gt;Auth-&gt;password que encripta de acordo com as definições do Salt definidas no core.php, assim podemos comparar&lt;pre name='code' class='brush: php'&gt;$this-&gt;data['User']['password'] == $this-&gt;Auth-&gt;password($this-&gt;data['User']['confirm_password'])&lt;br /&gt;&lt;/pre&gt;Rá!&lt;br /&gt;&lt;br /&gt;P.S.: Agora, sempre que o usuário retornava a tela do formulário (por erro em algum campo) o campo senha ficava enorme, pois estava preenchido com a senha encriptada. Para isso sempre que ocorre um erro de confirmação de senha eu limpo o password e o confirm_password, e quando ocorre erro em outro campo eu copio o valor do confirm_password para o password!&lt;br /&gt;&lt;br /&gt;Abração,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151990965170112620-2562603755709941527?l=cakenaveia.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cakenaveia.blogspot.com/feeds/2562603755709941527/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/confirmacao-de-senha.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/2562603755709941527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9151990965170112620/posts/default/2562603755709941527'/><link rel='alternate' type='text/html' href='http://cakenaveia.blogspot.com/2010/01/confirmacao-de-senha.html' title='Confirmação de senha'/><author><name>Carlitos</name><uri>http://www.blogger.com/profile/03583265400502617520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
