Selects aninhados – fazendo uma busca

Provavelmente já existem muitos tutoriais na net de como fazer uma busca por selects aninhados usando (a metodologia) ajax. Mas, como na web sempre tem gente nova chegando, e novas abordagens são sempre bem-vindas, vou mostrar como fazer uma dessas buscas de uma forma bem simples.

O que é necessário: um banco MYSQL rodando, PHP (versão 4 já da conta) e a biblioteca javascript prototype.

Tendo os ingredientes à mão, vamos criar um banco de dados com duas tabelas:

bandas: campos ID e NOME

discos: campos ID, ID_BANDA, NOME



A idéia é que a tabela bandas liste várias bandas (sendo ID chave primária), e a tabela discos vai guardar uma lista de discos referentes às bandas inseridas na outra tabela (usando ID_BANDA para referenciar a qual a banda o disco pertence).

Segue um dump do banco:

CREATE TABLE `bandas` (
  `id` int(11) NOT NULL auto_increment,
  `nome` varchar(128) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Extraindo dados da tabela `bandas`
--
INSERT INTO `bandas` VALUES (1, ´Iron Maiden´);
INSERT INTO `bandas` VALUES (2, ´Metallica´);
INSERT INTO `bandas` VALUES (3, ´Sepultura´);
-- --------------------------------------------------------
--
-- Estrutura da tabela `discos`
--
CREATE TABLE `discos` (
  `id` int(11) NOT NULL auto_increment,
  `id_banda` int(11) NOT NULL,
  `nome` varchar(128) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
--
-- Extraindo dados da tabela `discos`
--
INSERT INTO `discos` VALUES (1, 1, ´Fear of the Dark´);
INSERT INTO `discos` VALUES (2, 1, ´The Number of the Beast´);
INSERT INTO `discos` VALUES (3, 2, ´Load´);
INSERT INTO `discos` VALUES (4, 2, ´Master of Puppets´);
INSERT INTO `discos` VALUES (5, 3, ´Chaos AD´);
INSERT INTO `discos` VALUES (6, 3, ´Arise´);





Tendo feito isso, monta-se uma página com um formulário que possui dois selects. Através de uma consulta SQL feita pelo PHP ,todos os registros da tabela bandas são retornados e o primeiro select é populado, colocando o value de cada option igual ao id da banda (ele será usado para fazer a consulta SQL na tabela discos de uma banda específica).

No onchange desse select, se chama uma função javascript:

– ela vai fazer uma requisição utilizando o objeto Ajax da (biblioteca) prototype, a uma página php chamada discos.php

– discos.php consulta a tabela discos e procura os discos de uma banda específica, retornando uma string no formato registro1|registro2|registro3…

– no retorno da função, por javascript é feito um split na string retornada e, com isso, recupera-se num vetor a lista de discos. Com isso, só é necessário apagar os ítens anteriores da lista, percorrer o vetor gerado pelo split e criar para cada item dessa lista uma option e adicioná-la (appendChild()) ao select.



Segue o código da página principal:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Exemplo de select aninhado</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
<script type="text/javascript">
    function buscadiscos(field){
        //requisita o serviço PHP que vai listar os discos de uma banda, pelo id
        new Ajax.Request(´discos.php?id=´ + $F(field), {
            onSuccess: function(transport) {
                //alert(transport.responseText);
                $("discos").innerHTML = "";
                var discos = transport.responseText.split("|");
                for(var i=0; i<discos.length; i++) {
                    if(discos[i]=="")
                        continue;
                    var li = new Element("li").update(discos[i]);
                    $("discos").appendChild(li);
                }
            }
        });
       
    }
</script>
</head>
<body>
<h1>Exemplo - select aninhado</h1>
<form id="busca_discos" name="busca_discos" method="POST" action="#">
    <label>banda:</label>
    <select id="bandas" onchange="buscadiscos(this);">
        <option value="-1">selecione...</option>
    <?php
        //conecta ao banco
        $link = mysql_connect(´localhost´, ´root´, ´´);
        mysql_select_db(´exemplo_select´, $link);
        //monta string que seleciona todas as bandas
        $sql = "SELECT * FROM bandas";
        $result = mysql_query($sql);
        while ($row = mysql_fetch_array($result)) {
            echo("<option value=´" . $row["id"] . "´>" . $row["nome"] . "</option>");
        }
    ?>
    </select>
    <br /><br /><br />
    <label>discos:<label>
    <select id="discos"></select>
   
</form>
</body>
</html>





Segue o código da página discos.php:

<?php
    //conecta ao banco
    $link = mysql_connect(´localhost´, ´root´, ´´);
    mysql_select_db(´exemplo_select´, $link);
    //monta string que seleciona todos os discos de uma determinada banda
    $sql = "SELECT * FROM discos WHERE id_banda=" . $_GET["id"];
    $result = mysql_query($sql);
    while ($row = mysql_fetch_array($result)) {
        echo($row["nome"] . "|");
    }
?>

 

Vale ressaltar que a maneira de discos.php retirnar os dados foi a mais simples possível – e de menor qualidade. Para melhorar o código, seria interessante retornar um XML ou retornar os dados no formato JSON (tanto o PHP5 tem métodos nativos para codificar dados em formato JSON, quando a biblioteca JSON tem para decodificar os mesmos).

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *