O uso de métodos para incrementar a parte visual e funcional de site é muito usada e não é de hoje. Mensagens popup, caixas de diálogo e DIVs “mágicas” são exemplos de algumas das milhares de possibilidades neste meio.
Estes (e outros) recursos são largamente usados na internet, mesmo que de forma imperceptível, transformando o ato de navegar em uma experiência mais prazerosa e funcional.
O que permite aos desenvolvedores colocar todo seu potencial à prova são ferramentas client-side como o JavaScript e o CSS. Podemos dizer que todo o dinamismo e a beleza de um site faz uso dessas duas tecnologias, excluindo algumas como Flash e o próprio Java.
E com AJAX?
Na prática: quando você clica em um link ou submete (posta) um formulário, uma requisição é enviada ao servidor (HTTP) e uma resposta é esperada pelo navegador, que causa uma atualização (refresh) ao chegar. Vamos supor que você clique ali na opção “Artigos” no menu lateral. O que acontece após o clique? Seu navegador envia uma requisição ao servidor, que retorna o resultado desta e, para o navegador mostrar esse resultado, você nota que a página teve que carregar novamente.
Agora, imagine você preenchendo um formulário que possui duas caixas de combinação. Na primeira você seleciona seu estado e na segunda você tem que selecionar sua cidade. Para isso temos duas tabelas no banco de dados, a primeira guardando os estados e a segunda guardando as cidades (que fazem referência direta aos estados da primeira tabela).
Assim que você seleciona o estado, o site faz uma requisição para que apareça somente as cidades do estado selecionado. Como dito anteriormente, isso causará uma atualização no site inteiro, e é aí que entra o astro deste artigo! Ao invés de enviar uma requisição normal ao servidor, podemos usar o AJAX para enviar uma requisição assíncrona, ou seja, que não faça o site ter aquela atualização que, se não for bem trabalhada, faz você acabar perdendo os outros campos preenchidos do formulário.
Este é um pequeno exemplo das infinitas possibilidades do AJAX. Neste primeiro artigo vou mostrar como fazer esta requisição utilizando somente JavaScript, XML e PHP. Na parte 2 vou mostrar como funcionam duas APIs que facilitam este processo e no último um exemplo totalmente funcional de tudo o que foi abordado. Espero que gostem.
Criando a consulta ao banco
Como foi dito, as requisições trabalham com o formato XML, por isso nossa consulta deve responder com XML.
Como fazer?
Seguindo o mesmo exemplo da cidade e estado, vamos criar o seguinte banco:
- Criando o banco de teste
CREATE DATABASE ajax;
- Com as seguintes tabelas:
- Tabela que guarda os estados
CREATE TABLE estados (
id int(3) NOT NULL auto_increment,
nome varchar(100) NOT NULL default "",
uf varchar(2) NOT NULL default "",
PRIMARY KEY (id)
)
- Tabela que guarda as cidades
CREATE TABLE cidades (
id int(3) NOT NULL auto_increment,
nome varchar(100) NOT NULL default "",
estado varchar(2) NOT NULL default "",
PRIMARY KEY (id)
)
Com o banco e as tabelas criadas, insira alguns valores para darmos continuidade.
Faremos o uso do PHP para consultar o banco e gerar o arquivo XML.
<?php
/*
* Arquivo consulta.php
*/
// Abre uma conexão com o banco
$conexao = mysql_connect("localhost", "root", "") OR DIE("Erro na conexão.");
// Seleciona o banco a ser utilizado
$banco = mysql_select_db("ajax") OR DIE("Erro ao selecionar o banco.");
// Realiza a consulta
$resultado = mysql_query( sprintf("SELECT id, nome FROM cidades WHERE estado=%d", $_REQUEST["estado"]) );
// Gera o XML com o resultado desta pesquisa
$XML = sprintf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
while ( $record = mysql_fetch_array($resultado, MYSQL_ASSOC) ) {
$XML .= sprintf("<cidade>\n");
$XML .= sprintf("<id>%s</id>\n", $record[´id´]);
$XML .= sprintf("<nome>%s</nome>\n", $record[´nome´]);
}
// HEADER do arquivo XML
Header("Content-type: application/xml; charset=iso-8859-1");
// Mostra os dados
printf("<cidades>\n%s</cidades>\n", $XML);
?>
Observe que foi usado o método $_REQUEST["estado"] para que o estado possa ser passado tanto por POST quanto por GET, isso vai de cada um.
Em posse da pesquisa, vamos ver como chamar este arquivo via JavaScript.
Segunda parte: Requisição JavaScript
A requisição
A requisição feita é pelo JavaScript usando um objeto milagroso, o XMLHttpRequest(). Mas como ele faz tal requisição?
Simples:
// Função que recupera os dados da pesquisafunction catchDados(valor) {
function catchDados(valor) {
// Instancia o objeto
ajax = new XMLHttpRequest();
// Recupera o combo-box ESTADOS
estados = document.getElementById(´estados´);
// Recupera o combo-box CIDADES
cidades = document.getElementById(´cidades´);
if (ajax) {
// Limpa o combo-box CIDADES
cidades.options.length = 1;
// Faz a requisição
ajax.open("POST", "consulta.php", true);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Vamos processar os estados da requisição
ajax.onreadystatechange = function() {
// Carregando...
if (ajax.readyState == 1) {
cidades.innerHTML = "Carregando...";
}
// Ao receber a resposta
if (ajax.readyState == 4 ) {
if (ajax.responseXML) {
montaCombo(ajax.responseXML);
} else {
cidades.innerHTML = "Selecione o estado.";
}
}
}
// Envia os parâmetros
var params = "estado="+valor;
ajax.send(params);
}
A função descrita acima faz a requisição e trata seus status (carregando e carregado) e, quando recebido o resultado, passa para a função ´montaCombo´ (descrita a seguir) que insere os dados do arquivo XML no combo.
function montaCombo(XML){
// Array com os dados das cidades
var CIDADES = XML.getElementsByTagName("cidade");
// Recupera o combo-box CIDADES
cidades = document.getElementById(´cidades´);
// Verifica se a consulta retornou alguma coisa
if (CIDADES.length > 0) {
// Lemos todo o arquivo XML
for(var i = 0 ; i < XML.length ; i++) {
item = XML[i];
ID = item.getElementsByTagName("id")[0].firstChild.nodeValue;
NOME = item.getElementsByTagName("nome")[0].firstChild.nodeValue;
cidades.innerHTML = "Escolha...";
// Aqui e DOM, assunto para um outro artigo
// Cria os dados dentro do combo
opt = document.createElement("option");
opt.value = id;
opt.text = nome;
cidades.options.add(opt);
}
} else {
// caso o XML retorne em branco
cidades.innerHTML = "Escolha o estado.";
}
}
Espero que não esteja muito confuso, pois a base é um tanto trabalhosa mesmo. Como se pode notar, há uma parte em que foi usada a expressão DOM. DOM é uma técnica para manipular objetos HTML em tempo real, assunto para um próximo artigo. O que é feito ali usando DOM é criar os ´options´ do combo-box com as opções retornadas pelo XML.
Próximo passo, nosso fomulário HTML.
Última parte: Formulário completo
Depois de termos entendido todas as funções, tanto PHP quanto JavaScript, vamos ao formulário principal do nosso teste.
<html>
<head>
<title>PHP + AJAX</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<h1>AJAX + PHP</h1>
Recuperando dados sem refresh, usando AJAX.
<br><br>
<form>
Estado:
<select name="estados" id="estados" onChange="catchDados(this.value);">
<option value="">Escolha...</option>
<?php
/*
* Carregando os estados
*/
$conexao = mysql_connect("localhost", "root", "") OR DIE("Erro na conexão.");
$banco = mysql_select_db("ajax");
$resultado = mysql_query( sprintf("SELECT id, nome FROM estados ORDER BY nome ASC") );
while ($record = mysql_fetch_array($resultado, MYSQL_ASSOC)) {
printf("<option value=\"%s\">%s</option>\n", $record[´id´], $record[´nome´]);
}
?>
</select>
<br>
Cidade:
<select name="cidades">
<option id="" value="">Escolha o estado...</option>
</select>
</form>
</body>
</html>
Pronto, espero vocês na próxima parte deste artigo, onde vamos facilitar estes códigos usando APIs.
Abraços.
Artigo originalmente publicado em VivaoLinux.com.br