And After - Design e Tecnologia por Sua Conta!
O desenvolvedor é um blog sobre desenvolvimento web, não tratando apenas de programação mas também compartilhando experiências, métodos, debates e tendências da internet.

O Desenvolvedor é um blog de www.andafter.org
Assinar o Feed RSS

Chris Benseler

[www]

Fotos sempre tiradas do lado direito do rosto. Que nem o Rei!
Viciado em web, trabalho com web. Javascript e (x)html são minha praia conhecida, e me arrisco com PHP e Java.
Na vida offline, futebol e música me distraem. E falar bobeiras com os amigos

Status
Karma: 16024
Opiniões: 30

Mais deste autor


Criando um auto-completar (ajax) com PHP e MYSQL

Criando um auto-completar (ajax) com PHP e MYSQL

Muito bomEste texto foi classificado como Muito bom
Em Internet, Programação
Por Chris Benseler
13 de Maio de 2008

Como fazer um autocompletar - exemplo prático com php e mysql

RSS Acompanhe O Desenvolvedor por Feeds!


Escrevi esse texto acho que um ano atrás, para um outro site (acabou não dando em nada). Estou reeditando o mesmo :)

Vamos ver como fazer o básico para um auto-completar de um input (parecido com o Google Suggest). No nosso caso, vamos procurar por usuários em uma tabela de um banco de dados. Para isso, utilizarei PHP[bb] no lado do servidor. Mas, a linguagem do lado do servidor não é o que realmente importa. Uma funcionalidade que utiliza a metodologia o modelo ajax[bb] deve ser: um cliente javascript acessando um serviço que está no servidor (tanto faz a tecnologia).

No nosso caso, criei uma página PHP (name.php) que:

  • recebe um parâmetro para ser utilizado como filtro na nossa consulta: $name = $_GET["name"];
  • conecta ao banco de dados (no caso, utilizei o MySQL), acessando uma base que contenha uma tabela pm_users (essa tabela tem duas colunas, id e fullName);
  • efetua uma consulta à tabela utilizando $name como filtro na busca pelo campo fullName;
  • monta um array com os registros que satisfazem a busca;
  • retorna esse array no formato JSON (http://json.org/). JSON é um tipo de formato de troca de dados amplamente utilizado na web hoje em dia (tem vantagens e desvantagens com relação ao XML. Em um post futuro falo a respeito de cada um. Por hora, pode-se achar na web bons textos a respeito). Para transformar o array no formato JSON, utilizei uma classe do Zend Framework (http://framework.zend.com/).

Feito o nosso serviço no lado do servidor, vamos nos preocupar agora com a apresentação: criei uma página simples, que contém um formulário com um label e um campo input. E ainda uma área (div), a qual será usada para mostrar os resultados do auto-completar.





Depois, foi criada a formatação CSS. O mais importante no CSS é ver que a div#usersList tem sua posição definida como absoluta, e não está visível quando se entra na página.
Ela só ficará visível quando o usuário estiver digitando na caixa de texto e retornarem resultados.

Agora, temos toda a parte de layout pronta. Falta ligarmos isso com o serviço.
Como faremos? Há inúmeras formas.
A grande maioria das pessoas que utiliza PHP no lado do servidor, ou usa algum frameworks como o Sajax e o Xajax para criar a chamada às funções automaticamente, ou cria arquivos PHP que geram arquivos XML e no lado do cliente, criam na mão javascript para ler e tratar esse XML.
Eu quis, nesse nosso exemplo, dar uma outra forma a vocês de como fazer; na página 1, fiz uma página em PHP que retorna dados no formato JSON. Se eu fiz isso lá, no cliente vou ter que ler os dados também no formato JSON.

Antes de chegar lá, vamos ver como fazer para chamar o serviço criado.

  • um listener foi criado no onload do documento: sempre que o evento onkeyup for disparado na nossa caixa de texto, faremos a requisição no servidor;
  • caso o campo de texto não tenha pelo menos 3 caracteres, garantimos que a lista de resultados seja escondida e saímos da função (esperando que tenhamos 3 caracteres pelo menos);
  • se tiver pelo menos esses três, caracteres, definimos a URL do nosso serviço (no caso, a página PHP name.php) e os parâmetros a serem passados na requisição (no caso, o parâmetro name com o valor a ser usado para filtrar); Obs.: no caso, passamos um parâmetro "rnd=" + Math.round()*4 , isso é necessário para evitar cache na requisição, problema comumente encontrado nos browsers IE6-;
  • então, usamos o método Request do objeto Ajax da biblioteca Prototype (http://prototype.js). Note que esse método é uma espécie de wrapper para a criação do (objeto) XMLHttpRequest. Se você, usuário, quiser, pode continuar com sua implementação na mão do XMLHttpRequest. O impacto é mínimo. Segue link da documentação da API, dessa classe utilizada: http://www.prototypejs.org/api/ajax;
  • em caso de sucesso na requisição, a função de callback onSuccess é chamada, passando transport como parâmetro; transport possui o conteúdo do que foi retornado pelo request. No nosso caso, lembram-se dos dados no formato JSON? Por isso que utilizamos o método evalJSON(boolean) para transformar esses dados em formato compreensível pelo javascript. Obs.: evalJSON(boolean) é um método da Prototype. Se você tiver implementado o XMLHttpRequest, deve fazer a conversão utilizando uma biblioteca adequada. Uma boa procurada no Google lhe trará ótimos resultados a respeito.
  • uma vez com os dados transformados num formato compreensível pelo javascript (no caso, um array), só o que nos é necessário é percorrer esse array, sabendo que cada item do array possui um array de duas posições, onde a primeira é o id e a segunda o nome do usuário (olha só aí o porque o JSON é um belo formato de troca de dados: os dados que vieram do SELECT lá no PHP seguem a mesma ordem agora no javascript; não é preciso criar um XML, usar um DTD, percorrer nós, ver atributos, etc...). Voltando ao nosso array, ao percorrê-lo, criamos um elemento do tipo a para cada registro, e vamos definindo seus atributos (href, title, innerHTML...) e adicionando (appendChild) à lista, formando assim o nosso auto-completar

Pessoal, no final teremos uma página (ok, layout está bem simples, mas o propósito é mostrar a funcionalidade) onde o usuário vai digitando num campo input e através de uma rotina em PHP vão sendo feitas consultas no banco de dados, com filtro de usuários



Os arquivos estão disponíveis para

download

. Podem mexer, utilizar onde quiserem, modificar.

O que você achou do texto?

  • Muito ruim
  • Ruim
  • Regular
  • Bom
  • Muito bom
Sua opinião é o que faz a comunidade funcionar, colabore para isso!

Tags: php, google, suggest, autocompletar, ajax, mysql

Enviar para um amigo
Você pode comentar, assinar o feed, conhecer mais sobre o autor e ajudar a divulgar este artigo em sua ferramenta favorita através dos botões abaixo.
  • Rec6
  • ueba
  • linkk
  • dihitt
  • linkloko
  • websapiens
  • linkto
  • Eu curti

Comentários

Guilherme Serrano

13/5/2008 20:31:00

Quanto mais eu estudo programação mais eu percebo que eu sou designer...

Baixei os arquivos e estou estudando aqui para utilizar essa técnica ninja que tu ensinou aí mas com uma utilidade um pouco diferente... ;)

Valeu Chris!

[Responder este comentário]

Cayo Medeiros aka. yogodoshi
[www]

15/5/2008 14:27:00

Por acaso você conhece um código de autocomplete feito em ASP clássico ??

Abraços!

[Responder este comentário]

Guilherme Serrano

15/5/2008 14:53:00

Eu não programo em php, só ASP clássico... mas ainda não adaptei esse exemplo do Chris (só baixei, olhei, fiquei apavorado e deixei de canto) ainda.

Se eu fizer um autocompletar em asp eu publico aqui... ;)

[Responder este comentário]

Chris Benseler

15/5/2008 15:51:00

Cayo, como eu falei ali no começo do post, a linguagem do lado do servidor não é o segredo.
Se você criar uma página name.asp que faça o mesmo que essa name.php que eu criei - ou seja, retorna uma lista no formato JSON (tem link de referência para os padrões desse formato) - é só alterar o javascript que faz a consulta, apontando a url para name.asp ao invés de name.php
O javascript, css e html continua igualzinho.

[Responder este comentário]

Guilherme Serrano

15/5/2008 15:57:00

foi o que eu pensei... agora tenho que descobri como é que funciona direitinho o JSON. Que preguiça...

[Responder este comentário]

Ricardo Miranda
[www]

20/5/2008 17:13:00

estou com uma duvida...ja consequi executar o descrito acima....porem como faço para exibir 2 campos de um array na busca .. tipo busco um nome e aparece para mim o auto-completar de nome + codigo desses prováveis itens..
quais alterações devo fazer nos arquivos acima???? obrigado..
Ricardo miranda
projeto final de faculdade me ajudem...

[Responder este comentário]

João F. Melo
[www]

21/5/2008 19:43:00

Muito bom mesmo, bom não, ÓTIMO.
Por estes dias estava tentando criar um script qie fizese isso, procurei na net mas nenhum até agora tinha funcionado. Mas, está lenta a procura mesmo eu usando no servidor pago ou localhost e só está retornando o nome quando já está quase todo completo.

[Responder este comentário]

Ricardo miranda

22/5/2008 17:52:00

consequi:
//seleciona a base
mysql_select_db("new");
//monta string SQL
$sql = "SELECT * FROM cadforn WHERE nomeforn like `".$name."%` order by nomeforn";
$result = mysql_query($sql);

while ($row = mysql_fetch_array($result)) {
# cria uma array com os dados do mysql
$array_tmp = array($row["codforn"], $array_tmp2 = array($row["codforn"], $row["nomeforn"]));
$array[] = $array_tmp;
}
$json = Zend_Json::encode($array);

echo $json;
?>

mostra o codigo + o nome do produto

[Responder este comentário]

Alan

2/7/2008 01:11:00

vo pode manndar estes arquivos pro meu email, alan.1001webs@gmail.com to tentando baixar e nao vem conropido

[Responder este comentário]

Estela

21/8/2008 09:06:00

Sei que o post é velho... mas eu to tentando usar essa sua dica, mas não estou conseguindo.. está dando um Warning: Zend_Json::include_once... se puderes me ajudar.. entre em contato.
Desde já agradeço.
valeus! =D

[Responder este comentário]

Chris Benseler

21/8/2008 13:02:00

Estela, você baixou o Zend framework?
Verifique se o caminho definido na primeira parte do código do require_once está apontando para o caminho certo do arquivo (para a pasta onde você o baixou e tudo mais).

Estela

21/8/2008 13:53:00

Ok.. esse problema foi resolvido...
agora o problema é o seguinte.
No methods.js eu dei um alert na minha resposta (transport), e o resultado é [object XMLHttpRequest] e não está trazendo o resultado na div...

Chris Benseler

21/8/2008 16:44:00

"transport" é um objeto XMLHttpRequest; se você der alert(transport.responseText) terá printada na tela uma string, no formato de um array (na verdade, a tal notação JSON).
Por isso é usado aquele método evalJSON() que vai transformar essa valor em um array compreensível para o javascript. Com esse array em mãos, a função vai percorrer o mesmo e printar na div os itens, um a um.
Se precisar de mais ajuda, Estela, envie um e-mail (cbenseler@gmail.com)

Estela

22/8/2008 09:04:00

Ok.. funcionando perfeitamente..
muito obrigada...
=)

[Responder este comentário]

Pita

25/8/2008 14:44:00

Salve!
Antes de mais nada, muito bom o código. Resolveu meu problema.
Mas acho que faltou uma coisa: dentro da lista criada, você poder percorrer via teclado.
Essa é minha luta nesse momento. Poderia me ajudar?

Fiquem em paz!

[Responder este comentário]

Chris Benseler

27/11/2008 12:21:00

Pita, eu comecei a fazer esse código uma certa vez. Vou buscar o que eu já havia feito e tentar dar continuidade :)

victor mangia
[www]

27/11/2008 08:48:00

estou tentando botar esse script pra funcionar, porem está dando este erro abaixo, alguem sabe oque é?

Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or `}`

[Responder este comentário]

victor mangia
[www]

27/11/2008 09:04:00

Resolvido, atualizado php4 > php5 :)

[Responder este comentário]

Chris Benseler
[www]

27/11/2008 12:22:00

Vou atualizar o post com essa informação da versão do PHP! Obrigado!

Dermeval
[www]

14/2/2009 15:09:00

Vou testar o código, se funcionar direito, vai ser uma mão na roda!!

[Responder este comentário]

Everton

3/6/2009 17:27:00

prototype.js
Erro na linha 12260:
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

[Responder este comentário]

Leandro

9/6/2009 21:15:00

cara show de bola, parabéns.
fácil de implantar, prático e eficiente.

se puder disponibilizar o lance de usar o teclado para percorrer a lista e informar como susbtituo o alert pelo recebimento do nome selecionado no campo do nome lhe agradeço muito.

mais um vez parabéns, excelente.

[Responder este comentário]

Leandro

10/6/2009 20:17:00

### preencher o campo com o item selecionado
talvez não seja a forma mais correta, mas funcionou.

se alguém tiver solução para o uso do teclado na listagem e como cancelar (ESC) a lista de sugestão, eu agradeço.
[ ]s

[code]
<tr>
<td>
<b>Nome Passageiro</b>
</td>
<td>
<input type=text autocomplete=`off`name=nome maxlength="50" size="40"
<?php if($_GET[`nome`]) echo "value=`".$_GET[`nome`]."`"; ?> >
<div id="usersList"></div>
</td>
</tr>
[/code]
[code]
// in methods.js
//cria um link
var a = document.createElement("a");
//cria link passando o nome por referencia para o pagina do form
a.setAttribute("href", "?nome=" + json[i][1]);
a.setAttribute("title", json[i][1] + ` Passaporte: ` + json[i][2] + ` CPF: ` + json[i][3]);
a.innerHTML = json[i][1];
// submete o form
a.onclick = function() {
$("usersList").style.display = "none";
document.forms.submit();
return false;
}
$("usersList").appendChild(a);
[/code]

Alessandra

14/7/2009 12:50:00

Olá, OTIMO SCRIPT, vc me tirou de uma grande encrenca... Só que na hora que ele busca no banco as palavras com acento aparecem codificadas com caracteres, vc pode me ajudar a arrumar isso? VALEUUU.

[Responder este comentário]

Chris Benseler

14/7/2009 16:48:00

Alessandra, acho que se você utilizar no php uma função de decodificar UTF-8 para retornar os dados, funciona, mas não tenho certeza.
Vou checar!
[]s!

Alessandra

14/7/2009 16:57:00

Olá, Funcionou legal a decodificar , só estou com um ultimo problema, a lista aparece legal, mas tipo se eu der um ESC ou clicar em outra area a lista nao some, vc pode me ajudar , o site q eu estou trabalhando é www.webfocobrasil.net/clientes/jobfull/
Obrigada mais uma vez!

[Responder este comentário]

Chris Benseler

3/8/2009 17:30:00

Alessandra, você precisa colocar no evento keyUp do body um controle para caso o usuário tecle esc e a popup estiver aberta, que a feche!

viConcursos
[www]

3/8/2009 15:14:00

Cara esse tuto foi demais .. tudo o que eu precisava.. parabens.. funcionou de boa..

[Responder este comentário]

Renata

1/12/2009 16:04:00

Olá, Chris, parabéns pelo tuto! Precisava exatamente de algo simples assim.

Vc disse para a Alessandra que para a lista desaparecer podemos colocar no evento keyup do body um controle. Eu fiz isso, mas ele ele apaga a lista e inclusive o que eu digitei também.

Preciso de ajuda, para fazer que esta lista apague automaticamente quando eu mudar de campo do formulário? ou que a tecla ESC apague somente a lista mas permaneça o que eu estou digitando no campo. Vi que mais pessoas tem esta duvida.

function keyPressHandler(event) {
var kC = (window.event) ? // MSIE or Firefox?
event.keycode : e.keycode;
var Esc = (window.event) ?
27 : e.DOM_VK_ESCAPE // MSIE : Firefox
if(kC==Esc)
$("usersList").style.display = "none";
}

[Responder este comentário]

Gustavo

17/8/2010 19:15:00

Olá Renata.
Vc conseguiu uma solução para esse seu problema ? Estou tendo a mesma dificuldade. Pode ajudar-me ?

weslley clyton

18/1/2010 09:02:00

ola... o sue post é muito interessante.. eu tentei implementar mas não consegui..
A unica mudança que coloquei no fonte foi trocar o banco e a tabrla do bd...

[Responder este comentário]

Odilon

22/2/2010 16:51:00

Amigo vc tem como colocar outro link para download, pq esse n ta funcionando, Obrigado


[Responder este comentário]

will

16/5/2010 14:52:00

seguinte fiz tudo bonitinho ou quase tudo, quando clico no nome que esta listado ele manda uma mesagem que cliquei e tais mais não mostra o que selecionei, se alguem sober como arrumar isso, quero que mostre na caxa o que eu selecionar na lista e num mandar uma mesagem, o resto ta tudo oks parabens pelo post.

[Responder este comentário]

Daniele Dantas
[www]

28/5/2010 17:36:00

Olá.. Show de bola. Só ficou faltando mesmo poder usar o teclado e aparecer no input o que foi selecionado. Alguém pode ajudar? bejios

[Responder este comentário]
Deixe seu comentário!

Nome (requerido)

E-mail (requerido - não será divulgado)

URL

Quanto é 3 + 3?




web tracker