Criar Combo Dinâmico em Ajax com jQuery + PHP

By on

Listando Paises, Estados, Cidades e Bairros

Após usar extensivamente este recurso que vou apresentar aqui decidi compartilhar como eu procedo para obter tal resultado.

OBS.: Considero aqui que você já tenha baixado e instalado a biblioteca jQuery (usei a versão 1.3.2).

Neste exemplo vou utilizar quatro tabelas no banco de dados:

Mãos à obra!

Para organizar nosso trabalho, e como isto deve ser testado primeiro, vamos então criar um diretorio em nosso servidor chamado “teste-combo”.

Feito isto, crie 3 arquivos:

  • index.php
  • combo.js
  • localizacoes.php

[ index.php ]

<head>
  <script src="jquery-1.3.2.min.js"></script>
  <script src="combo.js"></script>
  <style>
    label {
      display:block;
    }
    label span {
      font-weight:bold;
      display:block;
    }
    select {
      width:150px;
    }
  </style>
</head>
<body>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <h1>Localizações</h1>
    <label><span>País:</span>
      <select name="pais" id="pais"></select>
    </label>
    <label><span>Estado:</span>
      <select name="estado" id="estado"><option value="0">--Primeiro o País--</option></select>
    </label>
    <label><span>Cidade:</span>
      <select name="cidade" id="cidade"><option value="0">--Primeiro o Estado--</option></select>
    </label>
    <label><span>Bairro:</span>
      <select name="bairro" id="bairro"><option value="0">--Primeiro a Cidade--</option></select>
    </label>
    <br />
    <label><input type="submit" value="Procurar"  />
  </form>
  <?php
  if ( $_POST ) {
    print '<pre>';
    print_r ( $_POST );
    print '</pre>';
  }
  ?>
</body>
</html>

OBS.: Eu não usei DOCTYPE ou outras tags e atributos HTML pois o objetivo é puramente ensinar como utilizar o recurso de combo dinâmico, por isto sinta-se à vontade de modifiicar como desejar. No arquivo acima, incluímos a biblioteca jQuery antes de qualquer arquivo, do contrário ela não funciona. Depois colocamos nosso arquivo combo.js. Criei um formulário com quatro SELECT’s respectivamente na ordem das localizações. Vamos ao nosso arquivo combo.js [combo.js]

 



  /*

   * Autor: Gilberto Albino
   * Data: 31/03/2009
   * Apaga isto por favor, hehe :D
   */
  jQuery(document).ready(
  function()
  {
    /*
     * Chamamos aqui a função que vai controlar os campos.
     * Desta forma, caso você precise repetir o combo dinâmico
     * basta trocar os ID's dos SELECT's
     */
    comboDinamico("pais", "estado", "cidade", "bairro");
    // suposição de segundo bloco de selects
    // comboDinamico("pais_cliente", "estado_cliente", "cidade_cliente", "bairro_cliente");
  }
);

  /*
   * função para carregar uma lista dinâmica
   */
  comboDinamico = function(pais, estado, cidade, bairro) {
    /*
     * Variáveis que precisamos pegar
     * Usamos getElementById() pois é assim que conseguiremos
     * passar o elemento por variável para jQuery
     */
    var pais   = document.getElementById(pais);
    var estado = document.getElementById(estado);
    var cidade = document.getElementById(cidade);
    var bairro = document.getElementById(bairro);
    /*
     * Carregamos a lista automaticamente quando a página carrega
     */
    $(pais).load('localizacoes.php?tipo=pais');

    /*
     * Populamos o combo dos estados quando trocamos um valor no pais
     * Os próximos blocos serão similares quanto à validação pelo valor igual à zero
     */

    $(pais).change(
    function() {
      if($(this).val() == 0) {
        alert('Você precisa informar um PAÍS!');
        $(this).focus();
      } else {
        $(estado).load('localizacoes.php?tipo=estado&amp;pais=' + $(this).val());
      }
    }
  );

    /*
     * Populamos o combo das cidades quando trocamos um valor no estado
     */

    $(estado).change(
    function() {
      if($(this).val() == 0) {
        alert('Você precisa informar o ESTADO!');
        $(this).focus();
      } else {
        $(cidade).load('localizacoes.php?tipo=cidade&amp;estado=' + $(this).val());
      }
    }
  );

    /*
     * Populamos o combo dos bairros quando trocamos um valor na cidade
     */
    $(cidade).change(
    function() {
      if($(this).val() == 0) {
        alert('Você precisa informar a CIDADE!');
        $(this).focus();
      } else {
        $(bairro).load('localizacoes.php?tipo=bairro&amp;cidade=' + escape($(this).val()));
      }
    }
  );

    /*
     * Uma validação simples só para garantir que não escolher um valor nulo
     */
    $(bairro).change(
    function() {
      if($(this).val() == 0) {
        alert('Você precisa informar o BAIRRO!');
        $(this).focus();
      } else {
        return true;
      }
    }
  );
  }

Como você pode notar eu comentei um pouco o código.

Mas só pra explicar rapidinho.

A cada alteração que realizamos num select ele carrega o arquivo “localizacoes.php” levando o tipo de consulta através da função load() da jQuery.

Vamos ver como ficou nosso arquivo localizacoes.php.

[localizacoes.php]

  

<?php
/*
* Bloco para testar a conexão
*/
try {
  /*
* Usei o banco mysql com o PDO.
* Se você estiver usando um servidor que não possua acesso ao PDO
* Ou não saiba como instalar o PDO, a lógica para trocar por funções mysql ou mysqli
* são visivelmente fáceis.
  */


  /*
* Variáveis de conexao
  */
  $servidor = 'localhost';
  $usuario = 'root';
  $senha = '';
  $banco = 'COLOQUE SEU BANCO AQUI';

  $con = new PDO( "mysql:host={$servidor};dbname={$banco}", $usuario, $senha );
  $con->query ( 'SET NAMES utf8' );
  /*
* Através deste bloco vamos alterar nossas consultas dinâmicas
*
* $sql = consulta própria do tipo
* $option = titulo que aparece no primeiro option da listagem
* $string = auxiliador da busca de resultados
  */

  switch ( $_GET['tipo'] ) {
    case 'pais' :
      $sql = "SELECT * FROM dados_paises WHERE status = 1";
      $option = 'o Pais';
      $string = 'iso3';
      break;
    case 'estado' :
      $sql = sprintf ( "SELECT * FROM dados_estados WHERE iso3 = '%s' AND status = 1", $_GET['pais'] );
      $option = 'o Estado';
      $string = 'uf';
      break;
    case 'cidade' :
      $sql = sprintf ( "SELECT * FROM dados_cidades WHERE uf = '%s'", $_GET['estado'] );
      $option = 'a Cidade';
      $string = 'nome';
      break;
    case 'bairro' :
      $sql = sprintf ( "SELECT * FROM dados_bairros WHERE cidade = '%s'", utf8_encode ( $_GET['cidade'] ) );
      $option = ' o Bairro';
      $string = 'nome';
      break;
  }
  /*
* Executamos o SQL aqui
  */
  $consulta = $con->query ( $sql );

  /*
* Iniciamos o resultado como null
  */
  $resultado = null;

  /*
* O primeiro option que vai aparecer já com o titulo dinâmico a partir de $option
  */

  $resultado = sprintf (
      '<option value="%s">Escolha %s</option>',
      0,
      $option
  );

  /*
* Um espaçador pra ficar elegante
  */

  $resultado .= sprintf (
      '<option value="%s">- - - - - - - - - - - - -</option>',
      0
  );

  /*
* Buscamos os resultados usando $c->string para identificar o ID dinamico pois varia, no caso temos iso3, uf, nome e nome
  */
  while ( $c = $consulta->fetch ( PDO::FETCH_OBJ ) ) {
    $resultado .= sprintf (
        '<option value="%s">%s</option>',
        $c->$string,
// o campo nome é comum a todos
        $c->nome
    );
  }

  /*
 * Imprimimos o resultado
  */
  print $resultado;

} catch ( Exception $e ) {

  /*
   * Se não aparecer nada é porque a conexao falhou :(
   */
  return null;
}
?>

Como você pode ver o código também está todo comentado .

Não há muito misterio nisto tudo, o que é preciso é uma boa lógica .

Para testar o bairro use a seguinte sequencia < strong > Brasil->Santa Catarina->Balneario Camboriu < strong >

Tente criar outras situações de combo dinâmico para estimular seu raciocínio .

Feedback

39 thoughts on “Criar Combo Dinâmico em Ajax com jQuery + PHP

  1. Funcionou perfeitamente. Parabens e obrigado pela contribui??o.

  2. Obrigado, Rubens, fico feliz que tenha sido proveitoso para voc

  3. Albino, mandou bem brother !!! muito bom !! parab?ns pelo tutorial… e aguardo outros mais !!! abs

  4. Poderia colocar um link com o exemplo on line… valeu!

  5. Obrigado, Alysson.

  6. Estou vendo isto Alysson.

  7. No Firefox funcionou uma beleza!
    N IE n?o funcionou.

  8. Avatar for Giba

    Gilberto Albino

    Estanho, porque eu fiz ele no IE.
    E foi testado em IE6, IE7, IE8, FF 2, FF3, Opera 9.3, Safari 3, Netscape e Chrome.

    E outra coisa a se notar que ? o jQuery quem trata o AJAX e ele faz perfeitamente em todos os IE6++, ent?o o problema deve ser com a vers?o de seu navegador.

    Veja na busca deste site:
    http://www.himoveis.com

    ? a mesma coisa! E funciona perfeitamente.
    Se n?o funcionar no seu verifique se o javascript est? habilitado para seu navegador.

  9. parabens pela pagina, de longe a mais organizada, bem, problema ? q ando com dificuldades pra fazer seu exemplo funcionar, nao consigo instalar, habilitar esse PDO, reviro foruns e mais foruns e nao consegui.. Se poder me dar uma mao agrade?o. abra?os at

  10. Avatar for Giba

    Gilberto Albino

    Bom, Daniel.
    Em rela??o ao PDO a habilita??o do mesmo ? simples demais.
    Voc? precisa estar rodando o PHP 5 ou superior,
    caso contr?rio n?o vai rolar mesmo, pois o PHP 4 n?o tem suporte ao PDO, entretanto existe uma classe que emula o PDO para PHP 4 neste link http://www.phpclasses.org/browse/package/2572.html

    Caso, este n?o seja seu caso,
    basta procurar no arquivo php.ini de seu PHP as linhas:
    ;extension=php_pdo.dll
    e
    ;extension=php_pdo_mysql.dll

    E retirar o ponto e v?rgula inicial de ambos.
    Ai voce reinicia o apache e j? vai funcionar.

  11. Resolvido problema, valeu pelo apoio, foi um pouco de azar e falta de aten??o, pra falar a verdade esses estao sendo os maiores problemas desde que comecei a mecher com constru??o web, vale destacar mais uma vez a linha

    “Para testar o bairro use a seguinte sequencia Brasil->Santa Catarina->Balneario Camboriu”

    Valeu, abra?os e novamente parabens pelo seu trabalho.

  12. Os links para os arquivos SQL est?o quebrados!

  13. Sou fraco ainda nesse lance de programa??o, por isso pesso a ajuda de voc?s. No final do resultado, ou no momento de apertar o bot?o, ou no momento que seleciona a ?ltima tabela, como eu crio um link para uma linha espec?fica de uma das tabelas?

  14. Cara, muito show esse teu exemplo… mas eu tow precisando de uma rela??o completa dos estados e cidades de todos os pa?ses…

    Tu saca onde posso achar essas informa??es, mesmo que seja pra catar na m?o mesmo??

  15. Avatar for Giba

    Gilberto Albino

    Gabriel, se me achar me fala, tamb?m t? procurando hehe

  16. Bom dia…..n?o manjo muito de php, mas encontrei seu artigo e curti demais!
    Mas ao enviar a consulta, ? exibido em baixo do “combo” uma mensagem mostrando o array que foi selecionado e n?o mostra o resultado dos bairro…Pq?

    At? mais e parabens pelos artigos
    Francisco

  17. case ‘tipoimovel’ :

    $sql = sprintf(“SELECT * FROM imoveis WHERE cidade=’%s’ AND bairro = ‘%s’ AND “, utf8_encode($_GET[‘bairro’], utf8_encode($_GET[‘cidade’])));
    $option = ‘ o Tipo’;
    $string = ‘tipo’;
    break;

    Como seria para um outro selec que busca a cidade e e bairro ao mesmo tempo?

  18. Giberto
    este seu script ? exatamente o que procurava
    muito obrigado
    Abra?os

  19. Velho !!! Muito bom este teu exemplo. Parab?ns mesmo.

  20. Avatar for Giba

    Cesar R Villalba

    Muy bueno todo, ya copie PDO paginacao y tambien localizador, muito obrigado From ARGENTINA, perto do Brasil, Ciudad de Posadas, Provincia de Misiones, ARG.

  21. Ola,
    Parab?ns pelo Post

    estou implementando este Combo em meu site e funcionou muito bem…

    porem.. ap?s mudar minhas urls para Amigaveis.. com

    Ex.
    RewriteEngine On
    RewriteRule ^cadastre-se\/?$ index.php?id=cad

    O combo parou de funcionar e abre a index no lugar do combo… muito estranho isso
    percebi tamb?m que tudo que pego via ajax e Jquery deu problema…

    entao o causador de tudo foi o .htaccess

    Teria alguma solu??o pro meu caso???

    preciso urgente.. ja ca?ei em tudo quanto foi canto e nao axo nada

    Pra ficar bem claro oque estou tentando dizer ? que..

    Quando Seleciono o PAIS

    ao inves de abrir os estados abre a pagina index dentro do select estados…

    A pagina index ? o site inteiro mesmo!..aff..rsrs muito loko isso…

    me ajudem alguem
    Obrigado!

    Leonardo

  22. Valeu pela dica irm?o… funcionou 100%…

  23. Eu não entendi o %s em localizacoes.php

    Alguém pode me explicar?

  24. Avatar for Giba

    outdoor lighting manufacturers

    O que eu acho difícil é encontrar um blog que pode prender-me por um minuto , mas seu blog é diferente. Bravo.

  25. Excelente script. Obrigado !

  26. Excelente post! Obrigado.

  27. Boa noite, ou ao clicar em em procurar esta aparecendo acesso proibido, alguem sabe me dar uma dica do que pode ser..

    http://localhost/teste/%3C?php%20echo%20$_SERVER%5B%27PHP_SELF%27%5D;%20?%3E

  28. queria saber como faria para ao selecionar todos os campos, ele me retornar um quinto valor que se encontra no banco de dados

    Ex. ao selecionar país, estado, cidade e bairro, ele consulte a base de dados e mostre abaixo todos os usuário que moram naquele endereço, por exemplo.

    Alguem pode me ajudar?

  29. Ola Gilberto,

    Seu script é fantástico, simples e prático de implementar… Mas ainda estou com um problema pequeno, vou te explicar:

    Imagine que meu último SELECT é na realidade uma lista de serviços. Quando o usuário executa o CHANGE desse select. O script precisa buscar o preço de venda desse serviço na base, e apresentá-lo em um input a seguir.

    Já procurei um exemplo similar na net, mas não sei como fazer isso com o jquery. Você pode me ajudar?

    Att
    Vinícius

  30. Gilberto boa tarde, pode me ajudar ? usei seu script e está funcionando perfeitamente ,preenche os combos tudo perfeito , utilizei $_POST para pegar os dados preenchidos e gravar no banco, porém ao gravar traz informações dos outros campos com por ex. ISO3, UF. como faço para gravar somente o que está selecionado nos combos?
    Obrigado

  31. Como altero os resultados para aparecer mais resultados do banco de dados tipo o nome endereço telefone

  32. obrigado, tive que adaptar muitas coisas, colocar mais 2 selects

    mais funcionou certinho do jeito que ta

    vlw ae gilberto albino

  33. Bem documentado. Obrigado

  34. query ( ‘SET NAMES utf8’ );
    /*
    * Através deste bloco vamos alterar nossas consultas dinâmicas
    *
    * $sql = consulta própria do tipo
    * $option = titulo que aparece no primeiro option da listagem
    * $string = auxiliador da busca de resultados
    */

    switch ( $_GET[‘tipo’] ) {
    case ‘pais’ :
    $sql = “SELECT * FROM dados_paises WHERE status = 1”;
    $option = ‘o Pais’;
    $string = ‘iso3’;
    break;
    case ‘estado’ :
    $sql = sprintf ( “SELECT * FROM dados_estados WHERE iso3 = ‘%s’ AND status = 1”, $_GET[‘pais’] );
    $option = ‘o Estado’;
    $string = ‘uf’;
    break;
    case ‘cidade’ :
    $sql = sprintf ( “SELECT * FROM dados_cidades WHERE uf = ‘%s'”, $_GET[‘estado’] );
    $option = ‘a Cidade’;
    $string = ‘nome’;
    break;
    case ‘bairro’ :
    $sql = sprintf ( “SELECT * FROM dados_bairros WHERE cidade = ‘%s'”, utf8_encode ( $_GET[‘cidade’] ) );
    $option = ‘ o Bairro’;
    $string = ‘nome’;
    break;
    }
    /*
    * Executamos o SQL aqui
    */
    $consulta = $con->query ( $sql );

    /*
    * Iniciamos o resultado como null
    */
    $resultado = null;

    /*
    * O primeiro option que vai aparecer já com o titulo dinâmico a partir de $option
    */

    $resultado = sprintf (
    ‘Escolha %s’,
    0,
    $option
    );

    /*
    * Um espaçador pra ficar elegante
    */

    $resultado .= sprintf (
    ‘- – – – – – – – – – – – -‘,
    0
    );

    /*
    * Buscamos os resultados usando $c->string para identificar o ID dinamico pois varia, no caso temos iso3, uf, nome e nome
    */
    while ( $c = $consulta->fetch ( PDO::FETCH_OBJ ) ) {
    $resultado .= sprintf (
    ‘%s’,
    $c->$string,
    // o campo nome é comum a todos
    $c->nome
    );
    }

    /*
    * Imprimimos o resultado
    */
    print $resultado;

    } catch ( Exception $e ) {

    /*
    * Se não aparecer nada é porque a conexao falhou 🙁
    */
    return null;
    }
    ?>

    Como tirar o PDO e ficar funcional?

    • Olá, Breno. A intenção não era demonstrar a conexão com o PHP, mas como funciona o combo em jQuery. Pretendo modificar este post para uma versão sem DB. Mil desculpas!

  35. estou com um problema, No momento que eu seleciono o pais(Brasil), abaixo, no campo estado ele mostra os 2 primeiros options(Selecione o Estado) e( ————–), mas não mostra nenhum estado, ele só mostra os estados quando eu troco a string %s no case’estado’ por ‘BRA’… Se alguem puder me ajudar. GRATO desde já pelo post me ajudou muito!

  36. Nao estou conseguindo escolher o estado, APENAS O PAIS!

Leave a Reply