Conheça o Plugfeed | » Início » Programação » Javascript » Preenchendo 3 combobox usando ajax
Conheça o Plugfeed | » Início » Programação » Javascript » Preenchendo 3 combobox usando ajax -->
 
Avaliação: | Publicado em: 12/09/2006
Preenchendo 3 combobox usando ajax
Rafael Martin Tem grande experiência com web usando as seguintes linguagens: asp, javascript, css, html, ajax, xml, dhtml, vb6, asp.net (c# e vb.net). Atualmente trabalha como Analista Desenvolvedor numa fábrica de sites, trabalhando em padrão Microsoft. Possui Certificado CCNA da Cisco, Dreamweaver MX 2004 e Segunça de Redes da Intel Genaration. É graduado em Sistema de Informação pela UNIb
Preenchendo 3 combobox usando ajax

Vamos criar nossa tabelas:

Tabela estados
   Campos: Cod, Estado

Tabela Cidades
   Campos: CodCidade, Cidade, CodEstado

Tabela Imoveis
   Campos: CodImovel, CodEstado, Imoveis, CodCidade


Arquivo default.asp

<%
 'AQUI REALIZAMOS A CONEXÃO COM O BANCO DE DADOS. NENHUM SEGREDO.
 Set conexao = Server.CreateObject("ADODB.connection")
 DSNtest = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.Mappath("dados_01.mdb")
 conexao.Open DSNtest

 sql = "select * from estados"
 set rs = conexao.Execute(sql)
%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>:: ::</title>
<style type="text/css">
<!--
/*AQUI APLICAMOS UMA PEQUENO CSS SIMPLES.*/
body {
 margin-left: 0px;
 margin-top: 0px;
 margin-right: 0px;
 margin-bottom: 0px;
}
-->
</style></head>

<body>
<!-- CHAMAMOS AQUELA FAMOSA FUNÇÃO DE AJAX QUE COMO SEMPRE DIGO É PADRÃO PARA TUDO.
VEJA EXPLICAÇÕES DELA EM OUTROS ARTIGOS MEUS, QUE SE TRATA DE AJAX.
 -->
<script language="javascript" src="ajax.js"></script>
<FORM method="post" name="frm1" id="frm1">
<table width="779" height="19" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td width="163" height="40" valign="top"><table width="163" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="29" background="Imagens/menu_001.gif"> </td>
      </tr>
      <tr>
        <td height="450" valign="top" bgcolor="#ECF2F0"><table width="150" border="0" cellspacing="0" cellpadding="0">
          <tr>
            <td height="19">
       <select style="width:200" id="estado" name="estado" onchange="trazdados();">
     <option value="0"></option>
                <%
    'ABAIXO NÓS PREENCHEMOS A PRIMEIRA COMBO. ATÉ AQUI TAMBÉM SEM NENHUM SEGREDO, NÉ?
    'NÃO ESQUEÇAM DE UMA COISA: PRECISAREMIS DO ID DA PRIMEIRA COMBO PARA PREENCHER O AS OUTRAS DUAS.
    'PORTANTO COLOQUEM NO VALUE DA COMBO O CÓDIGO DELA. PARA PEGARMOS DEPOIS...
    while not rs.EOF
    %>
                <option value="<%Response.Write(rs("COD") & "|" & rs("ESTADO"))%>" <%=selected%>><%=rs("ESTADO")%></option>
                <%
       rs.MoveNext
      wend
       
      rs.close
      set rs = nothing   
      %>
              </select>
            </td>
          </tr>
          <tr>
            <td height="19">
   <!-- VEJAM QUE AQUI EU NÃO FAÇO A SEGUNDA COMBO. COLOCO ELA VAZIA, APENAS PARA QUANDO O USUÁRIO ENTRAR
    VER QUE TEM A COMBO.
    E REPAREM QUE EXISTE ABAIXO ISSO: <span id='divcombouf'>. ESSA DIVI SERÁ A SEGUNDA COMBO QUE VIRÁ PREENCHIDA APÓS
    SELECIONAR UM REGISTRO NA PRIMEIRA COMBO. MAIS A FRENTE SERÁ EXPLICADO COMO E QUAL A FUNÇÃO QUE FAZ ISSO.
     -->
   <span id='divcombouf'>
              <select style="width:200" id="cidade" name="cidade" onChange="dadoscidade();">
      <option value="0"></option>
     </select>
   </span>
   </td>
          </tr>
          <tr>
            <td height="19">
   <!-- ESSA É A TERCEIRA COMBO. A EXPLICAÇÃO DA SEGUNDA (ACIMA) É EXATEMENTE IGUAL. NÃO MUDA NADA. -->
   <span id='divcomboimovel'>
              <select style="width:200" id="imovel" name="imovel">
                <option value="0"></option>
              </select>
   </span>
   </td>
          </tr>
          <tr>
            <td height="19"> </td>
          </tr>
        </table></td>
      </tr>
    </table></td>
    <td width="453"></td>
    <td width="163" valign="top"><table width="163" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="29" background="Imagens/menu_002.gif"> </td>
      </tr>
      <tr>
        <td height="450" bgcolor="#F9FBFA"> </td>
      </tr>
    </table></td>
  </tr>
</table>
<table width="779" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="33" background="Imagens/barra_003.gif"> </td>
  </tr>
</table>

<!-- AQUI COMO JÁ TINHA DITO PRECISO DOS ID'S DOS REGISTROS QUE ESTÃO NA COMBO PARA PODER PREENCHER CADA UMA.
ENTÃO CRIA - SE UM CAMPO HIDDEN PARA CADA COMBO. ASSIM QUANDO SELECIONAR UM REGISTRO, O ID DELE IRÁ PARA OS CAMPOS HIDDEN'S.
ISSO VALE PARA AS TRÊS COMBOS.
 -->
<input type="hidden" name="codestado" id="codestado" value="<%=codestado%>" size="3">
<input type="hidden" name="codcidade" id="codcidade" value="<%=codcidade%>" size="3">
<input type="hidden" name="codimovel" id="codimovel" value="<%=codimovel%>" size="3">
</form>
</body>
</html>

<script>

//ESSA FUNÇÃO IRÁ TRAZER O ID DO ESTADO SELECIONADO NA PRIMEITA COMBO PARA PODERMOS PREENCHER A SEGUNDA E TERCEIRA COMBO.
function trazdados()
{
    //AQUI "INFORMAMOS" QUE O PRIMEIRA COMBO SERÁ SELECIOANDA E DEPOIS DAMOS UM SPLIT NA BARRA (|) QUE
    //SEPARA OS VALORES QUE ESTÃO NO VALUE DA COMBO1. SE VC'S EXIBREM O CÓDIGO FONTE NO BROWSER VERÃO QUE A COMBO1 ESTARÁ ASSIM:
    // IDESTADO | NOMEESTADO.
    var arr = new String(frm1.estado.value);
    arr = arr.split('|');

  //AQUI TRAZEMOS APENAS O ID DE CADA ESTADO QUE FOR SELECIONADO.  
    frm1.codestado.value = arr[0];

  combocidade(); //CHAMA A FUNÇÃO AJAX QUE PREENCHER A COMBO CIDADE, ASSIM QUE É SELECIONADO UM REGISTRO NA COMBO1.
  comboimovel(); //CHAMA A FUNÇÃO AJAX QUE PREENCHER A COMBO IMÓVEK, ASSIM QUE É SELECIONADO UM REGISTRO NA COMBO1.   
      
}

//AQUI É A FUNÇÃO QUE PREENCHE A COMBO CIDADE.
//NÃO VOU ME APROFUNDAR NA EXPLICAÇÃO DESSA FUNÇÃO, JÁ QUE NOS OUTROS ARTIGOS QUE FIZ SOBRE AJAX, TEM A EXPLICAÇÃO SOBRE ELA.
//MAS REPAREM NO NOME DA DIV QUE DEMOS AQUI: divcombouf. É O MESMO NOME QUE DEMOS NO ID DAQUELA DIV QUE EXISTE ANTES DA COMBO2 NA PÁGINA.

function combocidade()
{
    var combouf = createXMLHTTP();
    combouf.open("post", "objestado.asp", true);
    combouf.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    combouf.onreadystatechange=function(){
     if (combouf.readyState==4){// abaixo o texto do gerado no arquivo executa.asp e colocado no div
      document.all.divcombouf.innerHTML = combouf.responseText;}}
      combouf.send("codestado=" + frm1.codestado.value);

}

//AQUI É A FUNÇÃO QUE SERÁ PREENCHIDA DE ACORDO COM O REGISTRO SELECIONADO NA COMBO1 E NA COMBO2.
//A EXPLICAÇÃO DA FUNÇÃO ACIMA VALE PARA ESSA TAMBÉM, JÁ QUE SÃO IGUAIS.
function comboimovel()
{
    var comboimovel = createXMLHTTP();
    comboimovel.open("post", "objimovel.asp", true);
    comboimovel.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    comboimovel.onreadystatechange=function(){
     if (comboimovel.readyState==4){// abaixo o texto do gerado no arquivo executa.asp e colocado no div
      document.all.divcomboimovel.innerHTML = comboimovel.responseText;}}
      comboimovel.send("codestado=" + frm1.codestado.value + "&codcidade="+frm1.codcidade.value);
 
}

//NESTA FUNÇÃO IREMOS OBTER O ID DA CIDADE. E PRA QUE PRECISAMOS DELA? PARA PREENCHER A COMBO IMÓVEL.
//A COMBO IMÓVEL SÓ TRARÁ REGISTROS DE ACORDO COM O REGISTRO SELECIONADO NA COMBO2.
//A EXPLICAÇÃO DA FUNÇÃO TRAZDADOS TAMBÉM VALE PARA ESSA.
function dadoscidade()
{
    var arr = new String(frm1.cidade.value);
    arr = arr.split("|");
  
    frm1.codcidade.value = arr[3];
   
    //VEJA QUE CHAMAMOS A FUNÇÃO QUE PREENCHE A COMBO IMÓVEL, DEPOIS QUE UM REGISTRO DA COMBO CIDADE É SELECIONADA.
    comboimovel();
}

//VOCÊS DEVEM TER REPARADO QUE NAS FUNÇÕES combocidade E comboimovel EXISTEM ESSE CAMINHO OBJETO/NOMEDOARQUIVO.ASP. CERTO?
//PORQUE CRIEI? PORQUE SE NO SEU SISTEMA VOCÊ PRECISAR USAR UMA DESSAS COMBOS, VOCÊ CHAMA APENAS O OBJETO.
//É COMO TRABALHAR COM ORIENTAÇÃO A OBJETOS.

//VEJA A EXPLICAÇÃO DAS PÁGINAS LOGO ABAIXO:
</script>

Arquivo objestado.asp

<%
'FAZ A CONEXÃO, SEM NENHUM SEGREDO.
Set conexao = Server.CreateObject("ADODB.connection")
DSNtest = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.Mappath("dados_01.mdb")
conexao.Open DSNtest

'RESGATA O ID DO ESTADO SELECIONADO PARA FAZER A SELAÇÃO DA COMBO DOIS (CIDADE).
codestado = request("codestado")

'AQUI ESTÁ NOSSO SELECT.
sql = "SELECT ESTADOS.COD, ESTADOS.ESTADO, CIDADES.CIDADE, CIDADES.CODCIDADE, IMOVEIS.CODIMOVEL, IMOVEIS.IMOVEIS "
sql = sql & "FROM (ESTADOS INNER JOIN CIDADES ON ESTADOS.COD = CIDADES.CODESTADO) "
sql = sql & "INNER JOIN IMOVEIS ON CIDADES.CODCIDADE = IMOVEIS.CODCIDADE WHERE ESTADOS.COD = " & codestado & " order by cidades.cidade"
set rs = conexao.Execute(sql)
%>

<!-- AUI MONTAMOS NOSSA COMBO DE CIDADE, CONFORME O ESTADO SELECIONADO -->
<table cellpadding="0" cellspacing="0" border="0">
 <tr>
  <td>
       <select style="width:200" id="cidade" name="cidade" onChange="dadoscidade(this.value);">
                <%
      while not rs.EOF
       
       'if CStr(codestado) = Cstr(rs("COD")) then
       ' selected = "selected"
       'else
       ' selected = ""
       'end if
      %>
                <option value="<%Response.Write(rs("COD") & "|" & rs("ESTADO") & "|" & rs("CIDADE") & "|" & rs("CODCIDADE") & "|" & rs("CODIMOVEL") & "|" & rs("IMOVEIS"))%>" <%'=selected%>><%=server.HTMLEncode(rs("CIDADE"))%></option>
                <%
        rs.MoveNext
      wend
       
      rs.close
      set rs = nothing   
      %>
              </select>
  </td>
 </tr>
</table>

<!-- VIRAM NENHUM SEGREDO -->

Arquivo objimovel.asp

<%
'CONEXÃO COM O BANCO.
Set conexao = Server.CreateObject("ADODB.connection")
DSNtest = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.Mappath("dados_01.mdb")
conexao.Open DSNtest

'RESGATAMOS O ID DO ESTADO E DA CIDADE. PORQUE? PORQUE QUANDO SELECIONARMOS UM ESTADO A COMBO DE CIDADES E INÓVEL SERÁ PREENCHIDA.
'E QUANDO SELECIONARMOS UMA CIDADE A COMBO IMÓVEL SERÉ PREENCHIDA COM O REGISTRO CERTO.
codestado = request("codestado")
codcidade = request("codcidade")

'UMA PEQUENA COMPRAÇÃO PARA NÃO FAZER TODA A INSTRUÇÃO DENTRO DO SELECT.
'BEM SIMPLES, NÃO É? RSRSRSRS
if len(codcidade) then
 filtro = " and CIDADES.codcidade = "&codcidade
else
 filtro = ""
end if

'NOSSA SQL. VEJA QUE CHAMA A VARIÁVEL FILTRO NO SQL. É COMO SUBSTITUIR AQUELE INSTRUÇÃO QUE ATRIBUI A FILTRO NA CLÁSULA SQL.
sql = "SELECT ESTADOS.COD, ESTADOS.ESTADO, CIDADES.CIDADE, CIDADES.CODCIDADE, IMOVEIS.CODIMOVEL, IMOVEIS.IMOVEIS "
sql = sql & "FROM ESTADOS INNER JOIN (CIDADES INNER JOIN IMOVEIS "
sql = sql & "ON CIDADES.CODCIDADE = IMOVEIS.CODCIDADE) ON ESTADOS.COD = CIDADES.CODESTADO "
sql = sql & "WHERE ESTADOS.COD = " & codestado & filtro & " ORDER BY IMOVEIS.IMOVEIS"
'response.Write(sql)
'response.End()
set rs = conexao.Execute(sql)
%>

<!-- AQUI MONTAMOS NOSSA COMBO DE IMÓVEL
PARA QUANDO FOR SELECIONADO UM REGISTRO NA COMBO ESTADO E NA COMBO CIDADE.
 -->
<table cellpadding="0" cellspacing="0" border="0">
 <tr>
  <td>
       <select style="width:200" id="imovel" name="imovel">
                <%while not rs.EOF%>
                <option value="<%Response.Write(rs("COD") & "|" & rs("ESTADO") & "|" & rs("CIDADE") & "|" & rs("CODCIDADE") & "|" & rs("CODIMOVEL") & "|" & rs("IMOVEIS"))%>" <%'=selected%>><%=server.HTMLEncode(rs("IMOVEIS"))%></option>
                <%
        rs.MoveNext
      wend
       
      rs.close
      set rs = nothing   
      %>
              </select>
  </td>
 </tr>
</table>

<!-- VIRAM SIMPLES TAMBÉM, RSRSRSRS -->

Até a próxima.

Arquivos anexos ao artigo

Louco por Ruby on Rails <andre@hotmail.com>
Meu Deus do céu cara, isso é ser simples ? isso foge de tudo oque é produtividade e qualidade... repense esses métodos pois existe forma melhor de fazer isso, boa sorte...
Kra, é que aqui o código pode parecer grande. Mais se vc ver bem é simples mesmo. Mais simples que isso não dá pra fazer.
É que vc pode estar achando que a forma de montar a combo está grande. Bem... existe muitas maneiras de montar uma combo. Eu uso várias depedendo do sistema ou da complexidade dele. Nesse caso é uma aplicação simples, portanto uso essa forma de montar a combo. O resto, função ajax e javascript, não tem como fazer mais simples do que já está.

e Vlw
Bom só que estou com uma duvida.
Quando é colocado mais de um IMOVEL na CIDADE a CIDADE se repete. A duvida é como colocar mais IMOVEIS sem que a CIDADE se repita.?
fernando <fernando@fernando>
péssimo. sem padrao w3c e ainda por cima o cara retorna os resultados dando innerHTML e nao new option = valores
Achei completamente equivocado também.

Acho que o site deveria ter um 'avaliador' de artigos para não postarem qq coisa...
Diogo Barbosa <dbarbosa@radial.r>
Ai grande, me matei usando esse seus códigos ai....até chegou a fazer algum sentido, porem tem uma parte que ele se perde, ele não consegue encontrar o codigo do estado na array, e então ele não joga esse cod dendtro da variavel codestado fazendo com que a codificação se perca toda pelo fato estar tudo atrelado as variaveis....voce poderia me dar uma força nesse código, pois na net foi o melhor que encontrei....mas mesmo assim não funcionõu 100%, teria como me dar um help???
Emerson Soares <soareseb@yahoo.com.br>
Eu gostei muito do seu post, parabéns.
Tudo isto pra preencher 3 combos?
BRUTALINO <www.peidei.net>
Cara, parabéns pela sua dedicação, vc deve ser um cara que gosta mesmo da coisa. Mas o problema é que realmente a produtividade cai com isso. Imagine vc ficando 1 ou 2 dias bolando essa função e fazendo outras obrigações. Desanima pensar que vc vai gastar esse tempo todo somente para preencher 3 combos, e que depois ser vivo nenhum que entenda de programação vai valorizar seu serviço. Estou precisando de uma solução para preencher 3 combos e fazer uma busca num banco de dados com os 3 resultados, tentei adaptar pelo seu código mas perdi totalmente a paciência...
Fernando
Eu parei de tentar entender o código na definição das tabelas.

Se for colocar banco de dados no codigo, normalize as tabelas defina PK e FK, use padrão ANSI nos comandos SQL.

Mas valeu a intenção....
renato lacerda <ghostlacerda@hotmail.com>
Ao invés de criticar, apontem soluções, caso sejam capazes. A primeira resposta para a solução de um problema nunca está perto da perfeição, gasta-se tempo e sinergia para a perfeição intangível.
Muito bom o código e foi muito útil para mim aqui no serviço... MEUS PARABÉNS!! Não achei nenhum código dos criticos por ai, por que será? criticar é fácil né? fazer são outros 500. aqui rodou legal.. só dei uma ajeitada e creiei algumas procedures.. o resto foi blz. VALEU!! Abraços!
Vanessa
Gostei muito do código estou usando meu serviço.Basta ler e entender.
Gostaria de saber como faria para criar uma quarta combo.

parabéns vanessa
Realmente isso não tem nada de simples. É preciso rever seus conceitos.
Luis
Ficou legal cara, pode estar um pouco fora dos padrões mas é o mais simples possível.
Elvis
Andei pesquisando sobre como fazer esse tipo de função na net e é dificil de encontrar. Esse foi o mais simples e funcional, fica mais facil de entender e adaptar as nossas necessidades. Padrão w3c? Isso se ajeita depois, o que importa é a parte funcional, a parte que interessa. E aos que não acham simples devem ser novatos, não querem passar trabalho e querem tudo "mastigadinho". Então façam um artigo com um código mais simples ainda.
que droga de artigo
Michaell Oliveira <michaell@mobsistemas.com.br>
Parabens pela iniciativa.

Porem tente "enxugar" esse codigo, esta simples porem necessita de automação, para que seja portado para outros usos, tente faze-lo de forma generica que o resultado será bom.

Parabens
Michaell Oliveira <michaell@mobsistemas.com.br>
Parabens pela iniciativa.

Porem tente "enxugar" esse codigo, esta simples porem necessita de automação, para que seja portado para outros usos, tente faze-lo de forma generica que o resultado será bom.

Parabens








Um produto Detetive.net