4 – AJAX (Asynchronous Javascript and XML): AJAX (acrônimo em língua inglesa de Asynchronous Javascript and XML, em português "Javascript e XML Assíncronos") é o uso metodológico de tecnologias como Javascript e XML, providas por navegadores, para tornar páginas Web mais interativas com o usuário, utilizando-se de solicitações assíncronas de informações. Foi inicialmente desenvolvida pelo estudioso Jessé James Garret e mais tarde por diversas associações. Apesar do nome, a utilização de XML não é obrigatória e as solicitações também não necessitam de ser assíncronas. AJAX não é um novo modelo para desenvolvimento Web. Os navegadores implementam essa tecnologia desde o ano 2000. Porém sua popularização nos últimos anos tem também trazido consigo muitas outras melhorias para a Web. Tem estimulado a construção de aplicações Web mais dinâmicas e criativas. AJAX não é uma tecnologia, mas um conjunto de tecnologias conhecidas trabalhando juntas, cada uma fazendo sua parte, oferecendo novas funcionalidades. 4.1 – Vantagens do AJAX: * Redução de banda A cada requisição que fazemos no navegador na Web, muitos objetos como menus, rodapé, figuras e dados, são carregados e a parte da informação o qual o usuário quer visualizar corresponde a uma pequena fração do que se vê na página carregada. Uma grande parte da banda é consumida nas transferências do conteúdo da página que está no servidor até o navegador (cliente). Toda e qualquer transferência de dados que ocorre num website usa banda. Banda é algo que se paga caro. O ponto forte de AJAX está exatamente na menor taxa de transferência de arquivos entre o servidor e o navegador, reduzindo muito mesmo o consumo de banda. * Rapidez Utilizando AJAX, ao carregar uma página o usuário terá facilidade e rapidez para buscar uma nova informação já que grande parte dos elementos de uma página estão carregados e visualizados no navegador. Isto torna a navegação uma tarefa mais ágil e agradável. - 31 - * Interatividade Os elementos básicos de interatividade e usabilidade são disponibilizados de forma a não ter um elevado consumo de banda. AJAX melhora e agrega facilidades para o usuário. * Validação de dados É sempre complicado lidar com segurança e principalmente na internet (tanto do lado do servidor e do navegador do usuário = trabalho dobrado). Com AJAX, todo o processo de validação fica no lado do servidor, que permite ocultar as regras de negócio. * Interfaces sofisticadas Fica bastante acessível colocar elementos gráficos de excelente qualidade sem ter a contrapartida de tornar a navegação mais lenta, pois cada componente não precisa ser novamente carregado a partir do servidor. Formulários podem ter múltiplas ações sem que o mesmo precise ser carregado a cada nova etapa de preenchimento. Tudo ocorre pontualmente sem a necessidade de renderizar a página novamente. 4.2 – Como funciona AJAX? - 32 - 4.3 - A Aplicabilidade do AJAX: Alguns usos mais comuns do AJAX podem ser listados: 4.3.1. Validação em tempo real: Validações que não possam ser feitas do lado do cliente, como, por exemplo, verificar se usuário já está cadastrado ou se a data informada é anterior à data atual. 4.3.2. Auto-Completar: Possibilita que o ao mesmo tempo em que o usuário for digitando, possa aparecer uma lista de possíveis respostas. Um bom exemplo é o Google Suggest. 4.3.3. Visualização de detalhes de um item: Ao invés de carregar todos os dados na tela ou então necessitar de popup’s, pode-se montar a lista de “itenspai” e dependendo da escolha, montar os detalhes do item. Um bom exemplo é o site da Oi (www.oi.com.br), onde escolhe-se o estado e em seguida, à medida que se digita no campo, são listadas as cidades iniciadas com as palavras digitadas do estado escolhido (Auto-Completar). 4.3.4. Controles de interface de usuário sofisticados (widgets): Controles dinâmicos como arvore de diretórios, menus, barras de progresso e interface ricas ou até mesmo jogos podem ser implementados sem necessidade de refresh. Um exemplo de interface rica pode ser visualizada no site Flickr (www.flickr.com), onde o usuário pode organizar uma coleção de fotos com diversos recursos, como por exemplo com utilização de drag-and-drop (arrastar e soltar). 4.3.5. Atualização de dados na página: Atualização de informações na página em tempo real sem a necessidade de refresh possibilita, por exemplo, o desenvolvimento de chats, acompanhamento de ações de bolsa, notícias ou aplicações semelhantes. 4.4 – Aplicações em AJAX: Para compreender como o AJAX trabalha, nós criaremos algumas aplicações. 4.4.1 – Sugestão de Nomes em AJAX: Primeiramente, nós vamos criar um diretório chamado ajax dentro de c:/wamp/www, ficando assim: c:/wamp/www/ajax Vamos criar o primeiro exemplo de Ajax dentro do subdiretório 01: c:/wamp/www/ajax/01 - 33 - Dentro deste diretório (c:/wamp/www/ajax/01), vamos criar os 03 (três) seguintes arquivos: index.htm <html> <head> <TITLE>Exemplo de AJAX 01</TITLE> <script src="clienthint.js"></script> </head> <body> <form> Nome: <input type="text" onkeyup="showHint(this.value)"> </form> <p>Sugestões: <span id="txtHint"></span></p> </body> </html> id="txt1" gethint.php <?php header("Cache-Control: no-cache, must-revalidate"); // Date in the past header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Fill up array with names $a[]="Anna"; $a[]="Brittany"; $a[]="Cinderella"; $a[]="Diana"; $a[]="Eva"; $a[]="Fiona"; $a[]="Gunda"; $a[]="Hege"; $a[]="Inga"; $a[]="Johanna"; $a[]="Kitty"; $a[]="Linda"; $a[]="Nina"; $a[]="Ophelia"; $a[]="Petunia"; $a[]="Amanda"; $a[]="Raquel"; $a[]="Cindy"; $a[]="Doris"; $a[]="Eve"; $a[]="Evita"; $a[]="Sunniva"; $a[]="Tove"; $a[]="Unni"; $a[]="Violet"; $a[]="Liza"; $a[]="Elizabeth"; - 34 - $a[]="Ellen"; $a[]="Wenche"; $a[]="Vicky"; //get the q parameter from URL $q=$_GET["q"]; //lookup all hints from array if length of q>0 if (strlen($q) > 0) { $hint=""; for($i=0; $i<count($a); $i++) { if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q)))) { if ($hint=="") { $hint=$a[$i]; } else { $hint=$hint.", ".$a[$i]; } } } } // Set output to "no suggestion" if no hint were found // or to the correct values if ($hint == "") { $response="Nenhum nome a sugerir!!!"; } else { $response=$hint; } //output the response echo $response; ?> clienthint.js var xmlHttp; function showHint(str) { if (str.length==0) { document.getElementById("txtHint").innerHTML=""; return; } xmlHttp=GetXmlHttpObject(); if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; } var url="gethint.php"; - 35 - url=url+"?q="+str; url=url+"&sid="+Math.random(); xmlHttp.onreadystatechange=stateChanged; xmlHttp.open("GET",url,true); xmlHttp.send(null); } function stateChanged() { if (xmlHttp.readyState==4) { document.getElementById("txtHint").innerHTML=xmlHttp.respo nseText; } } function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } Para verificar se o exemplo está funcionando corretamente, vamos iniciar o WampServer, clicar em Localhost. Em “Your Projects”, clique no diretório ajax e no subdiretório 01. Comece a digitar algum nome e veja as sugestões logo abaixo. Observe que o arquivo gethint.php possui um array estático com várias sugestões de nomes, os quais serão informados como Sugestões. - 36 - 4.4.2 – Ajax e PHP - Carregando dados sem refresh: Vamos fazer agora um exemplo prático utilizando PHP e Ajax junto com o Banco de Dados MySQL. A idéia é utilizar Javascript para transformar suas páginas em aplicações, de modo que não precise recarregar a tela cada vez que o usuário clicar em alguma coisa. Como exemplo, criaremos um script com dois ComboBox onde, no primeiro, o usuário selecionará o estado desejado e o segundo apresentará (sem refresh) as cidades correspondentes ao estado selecionado acima. Hoje em dia existem muitos frameworks que nos auxiliam a construir aplicações utilizando PHP e Ajax, mas agora vamos construir um exemplo na "unha", sem a utilização desses frameworks para que vocês possam ter uma noção de como é feito todo o processamento, bem como o funcionamento do Ajax. O primeiro passo será criar o database e as tabelas de estados e cidades no MySQL. Crie uma nova base de dados no MySQL chamada ajax. Dentro do database ajax, crie as duas tabelas (estados e cidades) utilizando o código abaixo: CREATE TABLE estados ( ID_ESTADO int(3) NOT NULL auto_increment , DSC_ESTADO varchar(100) NOT NULL default "" , SIGL_ESTADO varchar(2) NOT NULL default "" , PRIMARY KEY (ID_ESTADO) ) TYPE=MyISAM; CREATE TABLE cidades ( ID_CIDADE int(3) NOT NULL auto_increment , DSC_CIDADE varchar(100) NOT NULL default "" , COD_ESTADO varchar(2) NOT NULL default "" , PRIMARY KEY (ID_CIDADE) ) TYPE=MyISAM; Agora vamos popular as tabelas. Para isso, utilize o código SQL abaixo: INSERT INTO estados VALUES(1, "São Paulo", "SP"); INSERT INTO estados VALUES(2, "Rio de Janeiro", "RJ"); - 37 - INSERT INTO estados VALUES(3, "Minas Gerais", "MG"); INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO cidades cidades cidades cidades cidades cidades cidades cidades cidades cidades cidades cidades cidades cidades VALUES(1, "Araras", 1); VALUES(2, "Leme", 1); VALUES(3, "São Carlos", 1); VALUES(4, "Rio de Janeiro", 2); VALUES(5, "Nova Iguaçu", 2); VALUES(6, "Nova Frigurbo", 2); VALUES(7, "Resende", 2); VALUES(8, "Angra dos Reis", 2); VALUES(9, "Belo Horizonte", 3); VALUES(10, "Bom Sucesso", 3); VALUES(11, "Ipatinga", 3); VALUES(12, "Monte Belo", 3); VALUES(13, "Ouro Preto", 3); VALUES(14, "Juiz de Fora", 3); Agora vamos criar os arquivos que serão utilizados no nosso segundo exemplo. Antes, nós vamos criar um subdiretório chamado 02 dentro de c:/wamp/www/ajax, ficando assim: c:/wamp/www/ajax/02 Dentro deste diretório (c:/wamp/www/ajax/01), vamos criar os 03 (três) seguintes arquivos: Nome do Arquivo: conecta.php Este arquivo faz a conexão com o MySQL. <? //CONECTA AO MYSQL $conn = mysql_connect("localhost", "root", "") or die("Erro na conexão com a base de dados"); //SELECIONA A BASE DE DADOS $db = mysql_select_db("ajax", $conn) or die("Erro na seleção da base de dados"); ?> O arquivo acima conecta com o MySQL passando como parâmetros o servidor, usuário e senha. Ele também seleciona o database a ser utilizado, nesse caso ajax. - 38 - Nome do Arquivo: index.php Essa página exibirá o formulário que conterá os combobox estados e cidades além da chamada ao AJAX. <? //CONECTA AO MYSQL require_once("conecta.php"); //PEGA OS ESTADOS $sql = "SELECT a.id_estado, a.dsc_estado, a.sigl_estado FROM estados a ORDER BY a.dsc_estado"; //EXECUTA A QUERY $sql = mysql_query($sql); $row = mysql_num_rows($sql); ?> <script language="JavaScript"> function Dados(valor) { //verifica se o browser tem suporte a ajax try { ajax = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { try { ajax = new ActiveXObject("Msxml2.XMLHTTP"); } catch(ex) { try { ajax = new XMLHttpRequest(); } catch(exc) { alert("Esse browser não tem recursos para uso do Ajax"); ajax = null; } } } //se tiver suporte ajax if(ajax) { //deixa apenas o elemento 1 no option, os outros são excluídos document.forms[0].listCidades.options.length = 1; idOpcao = document.getElementById("opcoes"); ajax.open("POST", "cidades.php", true); ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - 39 - ajax.onreadystatechange = function() { //enquanto estiver processando...emite a msg de carregando if(ajax.readyState == 1) { idOpcao.innerHTML = "Carregando...!"; } //após ser processado - chama função processXML que vai varrer os dados if(ajax.readyState == 4 ) { if(ajax.responseXML) { processXML(ajax.responseXML); } else { //caso não seja um arquivo XML emite a mensagem abaixo idOpcao.innerHTML = "--Primeiro selecione o estado--"; } } } //passa o código do estado escolhido var params = "estado="+valor; ajax.send(params); } } function processXML(obj){ //pega a tag cidade var dataArray obj.getElementsByTagName("cidade"); = //total de elementos contidos na tag cidade if(dataArray.length > 0) { //percorre o arquivo XML paara extrair os dados for(var i = 0 ; i < dataArray.length ; i++) { var item = dataArray[i]; //contéudo dos campos no arquivo XML var codigo = item.getElementsByTagName("codigo")[0].firstChild.nodeValue; var descricao = item.getElementsByTagName("descricao")[0].firstChild.nodeValue ; idOpcao.innerHTML = "--Selecione uma das opções abaixo--"; //cria um novo option dinamicamente var novo document.createElement("option"); //atribui um ID a esse elemento novo.setAttribute("id", "opcoes"); //atribui um valor = - 40 - novo.value = codigo; //atribui um texto novo.text = descricao; //finalmente adiciona o novo elemento document.forms[0].listCidades.options.add(novo); } } else { //caso o XML volte vazio, printa a mensagem abaixo idOpcao.innerHTML = "--Primeiro selecione o estado--"; } } </script> <html> <head> <title>127º artigo PHP</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body bgcolor="#FFFFFF"> <h1>Carregando cidades sem dar refresh na página usando AJAX + PHP</h1> <form name="frmAjax"> Estado:&nbsp; <select name="listEstados" onChange="Dados(this.value);"> <option value="0">Selecione o estado >></option> <? for($i=0; $i<$row; $i++) { ?> <option value="<? echo mysql_result($sql, $i, "id_estado"); ?>"> <? echo mysql_result($sql, $i, "dsc_estado"); ?></option> <? } ?> </select> <br><br> Cidade:&nbsp; <select onChange="alert(this.value);"> <option id="opcoes" selecione o estado--</option> </select> </form> </body> </html> name="listCidades" value="0">--Primeiro - 41 - Nome do Arquivo: cidades.php Este script montará um arquivo XML utilizando o estado selecionado pelo usuário. Essa página será chamada pelo index.php utilizando Ajax. <? //CONECTA AO MYSQL require_once("conecta.php"); //RECEBE PARÃMETRO $pEstado = $_POST["estado"]; //QUERY $sql = " SELECT a.id_cidade, a.dsc_cidade FROM cidades a WHERE a.cod_estado = ".$pEstado." ORDER BY a.dsc_cidade"; //EXECUTA A QUERY $sql = mysql_query($sql); $row = mysql_num_rows($sql); //VERIFICA SE VOLTOU ALGO if($row) { //XML $xml = "<?xml version=\"1.0\" encoding=\"ISO-88591\"?>\n"; $xml .= "<cidades>\n"; //PERCORRE ARRAY for($i=0; $i<$row; $i++) { $codigo = mysql_result($sql, $i, "id_cidade"); $descricao = mysql_result($sql, $i, "dsc_cidade"); $xml .= "<cidade>\n"; $xml .= "<codigo>".$codigo."</codigo>\n"; $xml .= "<descricao>".$descricao."</descricao>\n"; $xml .= "</cidade>\n"; }//FECHA FOR $xml.= "</cidades>\n"; //CABEÇALHO Header("Content-type: application/xml; charset=iso8859-1"); }//FECHA IF (row) //PRINTA O RESULTADO echo $xml; ?> - 42 - Agora vamos destrinchar este código para facilitar o entendimento. Linha 3 -Incluímos o arquivo conecta.php - responsável pela conexão com o MySQL. Linha 6 -Montamos a query que será responsável por trazer os estados cadastrados na tabela. Linha 12 -Executamos a query. Linha 14 -Total de linhas retornadas pela consulta. Linha 18 -A função Dados é responsável por tudo, mas no pedaço acima é verificado se o browser suporta Ajax. Verificamos se existe o objeto XMLHttpRequest que nos permite que as requisições sejam feitas via browser de modo assíncrono com o servidor através de JavaScript sem que haja a necessidade da atualização da página. No IE o objeto é um ACTIVEX e no Mozzila e Safari é um objeto nativo. - 43 - Linha 44 - Chamamos o método OPEN, passando como parâmetros o método desejado (POST ou GET), a url a ser requisitada e um flag indicando se a chamada é assíncrona ou não. Linha 45 -Cabeçalho para corrigir os problemas de acento. Linha 49 -É verificado o valor da variável readyState que pode ter cinco valores: 0 (não iniciado), 1(carregando), 2(carregado), 3(interativo) e 4(concluído). Linha 54 -Verifica se foi retornado um arquivo XML, caso tenha chama a função ProcessXML(); Linha 64 -Passamos a função o estado selecionado pelo usuário. Linha 73 - Verificamos a quantidade de elementos contidos na tag CIDADE. Linha 76 -Percorremos o arquivo XML. Linha 80 -Pegamos o valor do campo descrição no arquivo XML e atribuímos a variável descrição em JavaScript. Linha 82 -Mudamos o texto do option. Linha 85 -Criamos dinamicamente um option para cada elemento encontrado no XML. Resultado final 1. Tela Inicial - 44 - 2. Selecionando um estado 3. Visualizando as cidades Obs: Testado e aprovado no IE 9.0, Firefox 11.0 e Google Chrome 18.0.1025.162 m - 45 -