quarta-feira, fevereiro 22, 2006

AJAX - Na prática e em Detalhes

Um dos classicos problemas de construir uma interface para uma aplicação Web é que uma vez que a pagina foi enviada para o cliente a conexão é encerrada imediatamente.

A qualquer tempo quando é necessária uma interação do usuário com a interface a requisição é enviada para o servidor que reconstroi a interface (Pagina) e envia de volta para o cliente, e dependendo da velocidade da conexão, a reconstrução de toda a pagina pode demorar bastante tornando a Aplicação Web pouco produtiva. Neste artigo abordarei uma solução que vem sendo adotada para a resolução deste problema, o uso do AJAX, que nada mais é do que a utilização conjunta de tecnologias já amplamente utilizadas: Javascript; DOM; XML, e principalmente a utilização do objeto XMLHttpRequest(), em fase de estudo e documentação pelo W3C e implementado pela maioria dos navegadores modernos.

Começaremos abordando um exemplo de aplicação bastante comum, em que se deseja fazer uma pesquisa em uma agenda.

Considere a existencia das seguintes tabelas:


Casdastro de Orgãos
Id Orgao Endereco
1 INSS Rua Castelo Branco, Centro, n. 554, Rio de Janeiro/RJ
2 IBAMA Rua das Flores n. 300, Centro
3 ... ...

Casdastro de Departamentos
Id id_orgao nome fone
1 1 Departamento de Fiscalização 0xx212344577
2 1 Departamento Administrativo 0xx21234578
3 ... ......


Em uma Aplicação tradicional você selecionaria em uma combo o orgão desejado e entao uma nova pagina será carregada e uma outra combo é preenchida com todos os depatamentos do orgão, nota-se desta forma um inconveninte, uma vez que somente um elemento da pagina será alterado, com AJAX somente a combo com os departamentos seria alterada sem a necessidade de toda a página ser carregada novamente.

Embora o AJAX possa ser implementado em outra linguagem, utilizaremos nessa abordagem o PHP, por ser a mais popular dentre as linguagens de script Server-Side. Na implementação do nosso pequeno exemplo teremos uma pagina principal chamada "agenda.php" e uma pagina que retornara os dados chamada de "pesq_depto.php" , as quais devem conter os seguintes codigos, que estão comentados para facilitar o entendimento:


Codigo fonte do script agenda.php

<html>
<head><TITLE>Exemplo de Agenda com Ajax</TITLE></head>
<style>
       td {border: 1px solid rgb(192, 192, 192);
           background-color: rgb(255, 255, 204);}
</style>

<SCRIPT language="JavaScript1.2" type="text/javascript">
var requisicao;

// Função para pegar os dados no servidor
// sem ter que carregar toda a pagina novamente
function LerDocXML(url)
{
    // Caso o browser seja baseado no Mozilla    
    if (window.XMLHttpRequest) {
        requisicao = new XMLHttpRequest();
        requisicao.onreadystatechange = ProcessaResposta;
        requisicao.open("GET", url, true);
        requisicao.send(null);
    // Caso o browser seja o Internet Explorer      
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (requisicao) {
            requisicao.onreadystatechange = ProcessaResposta;
            requisicao.open("GET", url, true);
            requisicao.send();
        }
    }
}

// Função para processar os dados retornados
// do servidor, ela é chamada automáticamente
// assim que o servidor responder à função
// LerDocXML
function ProcessaResposta()
{
    if (requisicao.readyState == 4) {
      if (requisicao.status == 200) {
            orgao  = requisicao.responseXML.documentElement;
            departamentos = orgao.getElementsByTagName('departamento');
            if (departamentos[0].firstChild.data!=0) {
                // Preenchimento da combobox de seleção de departamentos
                // Com dados retornados
                selec_depto = document.getElementById("depto");
                selec_depto.options.length=0;
                for(x=0; x<departamentos.length;x++) {
                    var o=new Option();
                    o.text=departamentos[x].getAttribute("nome");
                    o.value=departamentos[x].firstChild.data;
                    selec_depto.options[selec_depto.options.length]=o;
                }
                // Preenchimento dos INPUT endereco e fone
                input_endereco = document.getElementById("endereco");
                input_endereco.value = orgao.getAttribute("endereco");
                input_fone = document.getElementById("fone");
                input_fone.value = departamentos[0].getAttribute("fone");
            }
      } else {
            alert("Ocorreu algum erro: " + requisicao.statusText);
       }
   }
}

// Função executada toda vez que houver alteração
// no campo de seleção de orgãos
function mudar_orgao(evnt, campo) {
    codigo = campo.value;
    url  = 'pesq_depto.php?orgao=' + codigo;
    //Chamada à função que solicitara dados no servidor
    //neste caso solicita a relação de departamentos
    //cujo o codigo de orgao seja o definido na variavel
    //codigo
   LerDocXML(url);    
}
function muda_depto() {
   //A ser implementada conforme necessidade
}
</script>
<?

// Parametros de conexao com a base de dados no servidor MySQL
$db_host="localhost";  // Servidor onde esta hospedada a base de dados
$db_user="nome_do_usuario";      // Usuario
$db_pass="senha";     // Senha
$db_name="agenda";       // Nome da Base de Dados

// Comando para conectar com o MySQL
$conexao=mysql_connect($db_host, $db_user, $db_pass);
if(!
$conexao) die("Erro ao conectar com o MySQL");

// Selecionando a base de dados
$base=mysql_select_db($db_name, $conexao);
if(!
$base) die("Erro ao selecionar a base");

// Formulario de pesquisa
?>
<FORM  ACTION="<? echo $HTTP_SERVER_VARS["PHP_SELF"]?>" METHOD="GET">
<table width="100%" >
    <col width="50%">
    <col width="50%">
    <TR >
        <TD>
            Selecione o Orgão
        </TD>
        <TD>
            Selecione o Departamento
        </TD>
    </TR>
    <TR>
        <TD>
            <SELECT tabindex="0"   id="orgao" name="orgao" ONCHANGE="return mudar_orgao(event, this)">
            <?
                
// Preenchimento deste SELECT com registro da tabela orgaos
                
$pesquisa = "select * from orgaos";
                
$tabela=mysql_query($pesquisa);
            while(
$registro=mysql_fetch_array($tabela)) {
                    
$codigo = $registro['id'];
                    
$orgao = $registro['orgao'];
                    echo
"<OPTION value=$codigo> $orgao";
            };
            
?>
            </SELECT>
        </TD>
        <TD>
            <SELECT  id="depto" name="depto" ONCHANGE="muda_depto(this)">
            </SELECT>
        </TD>
    </TR>
    <TR >
        <TD colspan="2">
            Endereço: <INPUT size="80" type="text" name="endereco" id="endereco">
        </TD>
    </TR>
    <TR>
        <TD colspan="2">
            Fone: <INPUT size="80" type="text" name="fone" id="fone">
        </TD>
    </TR>
</table>
</form>
</html>






Codigo fonte do script pesq_depto.php

<?
header
('Content-Type: text/xml');
$db_host="localhost"; // local onde esta a base de dados
$db_user="nome_usuario";     // nome do usuario na base
$db_pass="senha";    // senha
$db_name="agenda";    // nome da base de dados
$con_link=mysql_connect($db_host, $db_user, $db_pass);
$base=mysql_select_db($db_name, $con_link);
echo
'<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>';
if(isset(
$_GET['orgao'])) {
    
$orgao = $_GET['orgao'];    
    
$pesquisa = "select endereco from orgaos where id = $orgao";
    
$tabela = mysql_query($pesquisa);
    
$registro=mysql_fetch_array($tabela);
    
$endereco = $registro["endereco"];
    echo
"<orgao endereco='$endereco'>";
    echo
"<departamentos>";
    
$pesquisa = "select * from departamentos where id_orgao = $orgao";
    
$tabela = mysql_query($pesquisa);
    while(
$registro=mysql_fetch_array($tabela)) {
        
$codigo = $registro['id'];
        
$nome = $registro['nome'];
        
$fone = $registro['fone'];
         echo
"<departamento nome='$nome' fone='$fone'>$codigo</departamento>";
    }
    echo
'</departamentos>';
} else {
    echo
"<orgao>0";
}
echo
'</orgao>';
?>




Como vocês podem ter observado no código assima o sistema todo é baseado em três funções em JavaScript LerDocXML(url), ProcessaResposta() e mudar_orgao(evnt, campo). Quando o usario seleciona um orgão o evento ONCHANGE da tag "select" chama a função mudar_orgao, que por sua vez forma uma url com o codigo do orgao selecionado (url = 'pesq_depto.php?orgao=' + codigo;) e chama a função LerDocXML passando como parametro a url, esta função por sua vez cria um objeto "requisicao" a partir da classe XMLHttpRequest, que entao define a função (requisicao.onreadystatechange = ProcessaResposta;) que tratara a resposta da pagina "pesq_depto.php" aberta pelo metodo open(). Quando o servidor retornar os dados a função ProcessaResposta é chamada e então preenche os demais campos do formulario dinamicamente.

O objetivo deste Post era mostrar na prática e em detalhes como é uma implementação de AJAX e espero ter conseguido.

Nenhum comentário: