Ajax (aquela maneira genial de atualizar conteúdo em uma página) tem sido a sensação nos últimos anos de desenvolvimento WEB. Lembro das minhas primeiras investidas na área em 2005, naquela época ainda um terreno desconhecido (pra mim) e bastante pedregoso. Anos mais tarde temos diversas ferramentas prontas e gratuitas para desenvolver tarefas em Ajax.
Mas nem só para atualizar conteúdo na página serve o famigerado recurso, pois Ajax é como um portal na quarta dimensão que pode ser aberto no browser e que permite tráfego de dados nas duas direções [servidor > cliente] e [cliente > servidor]. No presente artigo vamos tratar do último caso: “como enviar dados de um formulário para o servidor sem recarregar a página toda após o envio?”
Nas minhas primeiras empreitadas nesta área vi que o terreno era árduo e acabei desistindo, mas a biblioteca dojo oferece uma solução com estilo.
Se vc ainda não conhece a biblioteca Javascript Dojo, recomendo uma olhada no artigo “Como funciona a biblioteca Javascript Dojo”, será de grande valia 😉
Um pouco de Teoria
Vejamos o que ocorre em uma situação de envio tradicional. Na figura 1, podemos identificar 2 arquivos principais, o da página index, ao qual foi incluso um formulário, e o arquivo que recebe os dados. Nestas circunstâncias o envio dos dados é definido simplesmente pelo atributo “action” da tag <form> e o método de envio (geralmente ”post”) é definido no atributo “method” da mesma tag. A tarefa é acionada quando o usuário clicar no botão definido pela tag <submit>.
No protocolo HTTP, o browser envia alguma informação ao servidor, e este precisa retornar uma resposta ao browser.
No momento do envio, a página toda sai de cena, e o browser envia uma requisição via HTTP ao servidor, para que o arquivo recebe_dados.php entre em ação.
Figura 1 - Envio de dados via post pelo método tradicional
Este arquivo efetua as tarefas subseqüentes como gravar as informações no Banco de Dados, e após envia um cabeçalho (header) ao browser, com uma diretiva para que o browser peça ao servidor novamente o carregamento de index.php. A URL desta diretiva pode conter uma variável com a resposta dizendo “Ok tudo ocorreu bem!”, ou “Heitaaa, deu problema!”.
Ex do código:
<?
//tarefas
…
//retorno
header(“location:index.php?resposta=”.$resposta);
?>
Bom, este é o cenário tradicional que todo WEB designer com experiência de formulários conhece.
A proposta deste post (aqui post significa artigo do blog hahaha), como dito anteriormente, é utilizar Ajax para que a página não saia de cena enquanto os dados são enviados para recebe_dados.php.
Tenha em mente que Ajax é um método de transferência de dados todo manipulado via Javascript.
A figura 2 ilustra o esquema que vamos utilizar com a API do Dojo, o xhrPost.
Figura 2 - Envio de dados com dojo xhrPost
Nesta figura procurei deixar claro que os dados contidos no Formulário agora pegam outro trajeto. Veja que agora, o xhrPost, dentro da própria página index.php é quem captura os dados contidos no formulário, e os envia para recebe_dados.php. Ele é uma espécie de agente atravessador que negocia a transferência dos dados, digamos… por debaixo dos panos, e ninguém vê que algo está indo para o servidor, pois index.php não sai de cena.
Assim, se faz necessário também uma modificação na forma do envio da resposta que recebe_dados.php deseja devolver a index.php. Veja que quem está em contado com o servidor neste momento não é o browser todo, mas apenas o objeto xhrPost, ele mesmo fica aguardando a resposta, a qual pode ser um outro HTML, ou um TEXTO qualquer. Mas não desejamos um simples texto, porém uma variável contendo um texto de resposta. Quando vc quer codificar variáveis com valores em um meio textual, geralmente se utiliza XML, JSON, CSV ou coisa parecida. Neste caso, o dojo oferece uma ferramenta simples para codificar as variáveis em JSON.
Quando o xhrPost recebe a resposta, ele a pode entregar para funções Javascript específicas que vão decodificar o resultado em JSON e por fim apresentar a mensagem na tela do usuário.
Enfim este é o efeito que desejamos. Vamos ás instruções?
Material necessário:
Básico:
- Arquivo HTML com formulário básico ( index.php )
- Arquivo para receber os dados e devolver uma resposta (recebe_dados.php)
- Biblioteca Javascript Dojo (veja como instalar aqui mesmo no Ahã… Programando…: instalacao-da-biblioteca-dojo)
Ferramentas pertencentes ao dojo:
-
dijit.dijit (layouts dojo)
-
dijit.form.Button (widget button)
-
dojo.parser (farejador que procura widgets no meio do HTML para ativar)
-
xhrPost (Api dojo para envio de dados via Ajax pelo método Post)
-
tundra.css (folha padrão da biblioteca dojo)
-
classe de conversão Json PHP (já vem de brinde com o Dojo)
-
alguns scripts adicionais pra organizar as coisas
Mãos á obra:
Nosso maior trabalho será com o arquivo index.php no qual precisamos adicionar as devidas funcionalidades do dojo.
Abaixo o código de index.php, desculpem a endentação que não é das melhores, por que foi adequada à largura disponível de área para textos do blog.
<?php
//charset
header(“Content-Type: text/html; charset=ISO-8859-1”,true);
//modifique aqui o caminho da url do dojo
//em seu servidor
$DOJO_URL=“http://localhost/dojo-release-1.3.0-src/”;
?>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
_<title>TESTE xhrPost</title>
_<link
__id=“themeStyles”
__rel=“stylesheet”
__href=“<?=$DOJO_URL;?>dijit/themes/tundra/tundra.css”>
_<script type=“text/javascript”
_________src=“<?=$DOJO_URL; ?>dojo/dojo.js”
_________djConfig=“isDebug:false, parseOnLoad: true”
_________charset=“utf-8”></script>
_<script type=“text/javascript” charset=“utf-8”>
__//carrega layer dijit para interfaces
__dojo.require(“dijit.dijit”);
__//botao do dojo p engatilhar o xhrPost
__dojo.require(“dijit.form.Button”);
__//varre o HTML em busca de widgets dojo__
__dojo.require(“dojo.parser”);
__//função [sendForm] para estabelecer o envio
__//dos dados via xhrPost. Esta função é executada
__//uma única vez quando a página é carregada, para
__//que seja estabelecida a comunicação entre o
__//FORM e o xhrPost, bem como colocar o gatilho
__//do xhrPost no botão “botao_submit_dojo” que é um
__//widget Dojo. Não funfa com botões tradicionais.
__function sendForm() {
___var button = dijit.byId(“botao_submit_dojo”);
___dojo.connect(
____button,
____“onClick”,
____function(event){
_____//para (stop) o evento submit original
_____event.preventDefault();
_____event.stopPropagation();
_____var deferred = dojo.xhrPost({
______//”form_teste” – id do formulário HTML
______//por este id o dojo localiza o FORM
______form: dojo.byId(“form_teste”),
______handleAs: “text”,
______load:resJsonOk,
______error:resJsonError
_____});//xhrPost
____});//function(event)
__}//function sendForm()
__//mensagem erro de comunicação com o servidor
__function resJsonError(data,ioArgs){
___var msg = ‘Nenhuma resposta do servidor.’;
___if(data)
____msg += ‘Ocorreram os seguintes erros em ‘;
____msg += ‘<b>recebe_dados.php:</b><br> ‘ + data;
___dojo.byId(“ct_msgs”).innerHTML = msg;
__}//function resJsonError(…)
__//recepção da MSG de retorno OK, recebe o conteúdo
__//JSON devolvido do recebe_dados.php, e extrai as
__//variáveis (status e msg) com seus respectivos valores
__function resJsonOk(data,ioArgs) {
___if(data){
____var d = dojo.fromJson(data),
____conteudo_msg = “STATUS: [“+d.status+“] <br>”;
____conteudo_msg += d.msg + “<br>”;
____dojo.byId(“ct_msgs”).innerHTML = conteudo_msg;
___}//if
__}//function resJsonOk(…)
__//executa sendForm quando a página for carregada
___dojo.addOnLoad(sendForm);
_</script>
</head>
<body class=“tundra”>
_<div id=“ct_msgs”></div>
_<div id=“ct_geral”>
__<!–Abaixo um formulário simplório com… –>
__<!–as configurações tradicionais –>
__<form id=“form_teste” method=“post”
___action=“recebe_dados.php”>
__ <!–Tags de entrada de dados… –>
__ <!–também tradicionais –>
___<label>Nome:</label>
___<input type=“text” name=“txt_nome” />
___<label>Endereço:</label>
___<input type=“text” name=“txt_endereco” />
___<!–botão especial, que é um WIDGET dojo –>
___<button dojoType=“dijit.form.Button”
____id=“submitButton”>Enviar</button>
__</form>
_</div>
</body>
</html>
Abaixo o código para recebe_dados.php que será utilizado em nosso teste. O código está bem comentado, dispensando maiores… comentários hehehe.
<?php
//endereço dojo no File System
$DFS=“c:/apache2.2/htdocs/dojo-release-1.3.0-src”;
//classe JSON PHP do dojo
require($DFS.“/dojo/tests/resources/JSON.php”);
/*
* Neste espaço poderiam haver tarefas para
* salvar os dados em BD
*
*/
//monta uma string com os dados recebidos
$dr =“Dados recebidos:”;
$dr.=” [‘nome’: “.$_POST[“txt_nome”].“, “;
$dr.=“‘endereço’: “.$_POST[“txt_endereco”];
$dr.=“]<br>”;
//Prepara a resposta de retorno em JSON, para
//cada variável a + adicionar um item no array
//com o nome da variável e seu respectivo valor
$ar = array(‘status’ => “ok”,
____________‘msg’ => $dr);
//cria o objeto manipulador de JSON
$json = new Services_JSON();
//gera uma string com o conteúdo do vetor
//codificado em JSON
echo $json->encode($ar);
?>
Podemos observar que recebe_dados.php, efetua a simples tarefa de receber os dados enviados, e devolvê-los através de variáveis codificadas em Json. É claro que recebe_dados.php poderia efetuar muitas outras tarefas, como por exemplo: verificar a validade dos dados recebidos, gravá-los no banco de dados, analisar o status da gravação no banco e gerar uma resposta e devolver. Porém vamos primar pela simplicidade por que o foco de nosso estudo é o funcionamento do xhrPost. Uma vez efetuadas as tarefas, o array PHP com as variáveis de resposta é lançado para o método encode do objeto $json, o qual retorna uma string JSON. Sempre que um browser roda um arquivo no servidor, e este possui um echo ou equivalente, uma strig de texto é devolvida para o browser automaticamente, e esta é exibida na tela. Porém em nosso caso o solicitante não foi diretamente o browser, porém o agente xhrPost que o fez enviando dados para o arquivo recebe_dados.php, naturalmente xhrPost aguarda alguma string de retorno vinda deste arquivo, pelo protocolo HTTP (veja novamente a figura 2). Juntando tudo isto, a resposta recebida virá em JSON, como no exemplo abaixo:
Variáveis:
“status” = ok,
“msg” = Dados recebidos: [‘nome’: Leonir, ‘endereço’: Rua Ah\u002e002e. Programando…!]
String Json:
{“status”:”ok”,”msg”:”Dados recebidos: [‘nome’: Leonir, ‘endereço’: Rua Ah\u002e002e. Programando…!]”}
Salve index.php, e recebe_dados.php na mesma pasta, de forma que vc possa acessar index.php através de seu servidor local. Aí é só colocar para rodar, estes códigos estão funcionando perfeitamente, foram testados, e copiados diretamente do editor PHP e Javascript que utilizo o APTANA.
Observação Importante: Ao copiar o código, e colar em seu editor substitua todas as aspas redigitando-as, ou através do search replace do editor. Isto devido ao fato que o wordpress substitui as aspas normais por umas mais bonitinhas porém inúteis, os interpretadores de código PHP e Javascript não as reconhecem.
É isto, experimente e deixe seu comentário.
Abraço e até o próximo post.