segunda-feira, novembro 13, 2006

Fazendo uma requisição assíncrona simples, com JQuery

Com o advento do ajax nós programadores estamos sempre utilizando essa ferramenta para um adicional em nossos sistemas. Seja carregando dados para preencher um dropdown, seja para carregar uma página inteira, as requisições assíncronas, junto do bom e velho “carregando...” viraram rotina em nossas vidas.

Tendo toda essa importância é claro que a JQuery não poderia não ter um módulo só para ajax. Vamos entender um pouco desse módulo da JQuery, e saber como incrementar nossa produtividade com ele.


Para essa nossa brincadeirinha vamos imaginar uma situação em que precisamos pegar as cidades de um estado escolhido por nosso usuário. Essa é uma situação bastante comum nos dias atuais. O usuário escolhe um Estado, nós carregamos as cidades daquele estado, e o usuário, então, escolhe a cidade.


Para isso, vou fazer um arquivo em php bem simples. Como o server-side foge do escopo deste post, vou colocar as cidades e estados como arrays mesmo.

Sendo assim, teremos 4 arquivos, a saber: ajax.js (nosso javascript), css.css (folha de estilos do nosso html), get_xml.php (gerador do xml no servidor) e teste.html (o nosso html para o exemplo).


Para realizar nossa chamada assíncrona com JQuery temos várias opções, que variam conforme sua necessidade. Vamos a algumas:

$.ajax( prop ) -> essa recebe um hash como parametro. Devemos especificar no hash as propriedades necessárias à requisição.

Ex.:


$.ajax( {type: “post”,
url: “teste.php”,
data: “parametro1=valor1¶metro2=valor2”,
success: function (result){ alert(“resultado da requisição: “+result);},
error: functin (){alert(“não deu para completar a requisição”);}
});

$.get( url, params, callback) -> uma chamada padrão do tipo “GET”. Params é um hash com pares atributo/valor para passar como parâmetros da url.


$.post( url, params, callback) -> como $.get(), mas este faz uma requisição do tipo “POST”.



Bom, já sabemos como utilizar, agora vamos ao nosso pequeno exemplo.

Começemos pelo HTML:


<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title> Teste ajax jquery </title>
<script type="text/javascript" src="jquery.js"></script>

<script type="text/javascript" src="ajax.js"></script>
<link type="text/css" href="css.css" rel="stylesheet" />
</head>
<body>

<div id="content">
<h3>Teste do ajax com jquery</h3>

<form name="form1" action="pega_valores.php">
<fieldset>
<legend>Escolha um estado abaixo:</legend>
<label for="estado">Estado:</label>
<select name="estado">

<option selected="selected">Escolha um estado</option>
<option value="sp">São Paulo</option>
<option value="rj">Rio de Janeiro</option>
<option value="mg">Minas Gerais</option>

</select>
<br />
<label for="cidade">Cidade:</label>

<select name="cidade">
<option selected="selected">Escolha uma cidade</option>

</select>
</fieldset>
</form>
<div id="loading" class="loading_hide">
Carregando...
</div>
</div>

</body>
</html>



Este é uma página simples, com um formulário com dois dropdowns e um div que será nosso "carregando...". Veja que não utilizamos nenhum evento dentro do html. Então estamos com lógica separada de conteúdo. Ótimo.

Vamos agora à nossa folha de estilos:


/* css.css */

fieldset {
border: 1px solid green;
}

legend {
color: #999;
}

#loading {
background: red;
color: white;
font-weight: bolder;
padding: 2px;
position: absolute;
left: 0;
top: 0;
}

.loading_hide {
display: none;
}




Aqui não tem muito segredo. Algumas cores, uma borda, e lá no final, a declaração que esconde o nosso "Carregando...".

Vamos ver como ficou nosso arquivo de geração de xml no servidor, em php:


<?php
$arr_cidades = array("sp" => array("São Paulo",
1 => "São Caetano",
2 => "Santo Amaro",
3 => "Santos"
), "rj" => array(
1 => "Rio de Janeiro",
2 => "Campos",
3 => "Niterói"
), "mg" => array(
1 => "Belo Horizonte",
2 => "Contagem",
3 => "Ouro preto",
4 => "Diamantina",
5 => "Poços de caldas"
)
);
if( !isset($_GET['estado']))
{
die("Erro, tente outra vez");
}
$str_estado = $_GET['estado'];
$arr_resultado_cidades = $arr_cidades[$str_estado];
header("Content-type: text/xml");
echo "<?xml version='1.0' ?>";
echo "<estado val='" . $str_estado . "'>";

foreach ( $arr_resultado_cidades as $int_index => $str_cidade)
{
echo "<cidade cdg='" . $int_index . "'>" . $str_cidade . "</cidade>";
}

echo "</estado>";
?>


Aqui também nada demais. Talvez seja até simplório demais, mas como php não é a nossa intenção neste post, fiz assim mesmo, simplificado.

Agora o que realmente faz a coisa funcionar. Nosso arquivo javascript. O script está bem comentado, então acho que não teremos muitos problemas. Veja que nosso script tem menos de 50 linhas. Se acha muito, tente fazer isso no braço e verá como ficará. :)

Nosso script:


//ajax.js
window.onload = start;

function start(){
var form1 = $("form[@name=form1]");//nosso form
var estados = form1.find("select[@name=estado]");//select dos estados

//chama a função loadCities quando o valor do select é modificado
$(estados[0]).change( function (){
loadCities( this.value);
});
}

function loadCities( estado ){
var url = "get_xml.php";
$("#loading").show("slow");//mostra o carregando...

$.get( url , {"estado": estado} , setCities);
//ajax em jquery, quando por get, use $.get(), quando por post, use $.post()
//os parametros são a url, os parametros da url, e a função callback. Se vc não fornecer os parametros da url e o segundo parametro da função
//for uma outra função, essa passa a ser a de callback.
//veja http://jquery.com/docs/AJAXModule/
}

function setCities(xmlCidades){
var cidades =$("form[@name=form1]").find("select[@name=cidade]");
xml_cidades = $("estado", xmlCidades);

cidades.empty();//tira os elementos 'antigos' do select
var oldOption = $(document.createElement("option"));//option com o valor 'Escolha uma cidade'
oldOption.append("Escolha uma cidade");//passamos o valor
//inserimos o option antigo no select
cidades.append(oldOption).change(function(){
form1.submit();
});//na hora que escolher a cidade, dispara o submit do form. O poder do encadeamento.

//colocamos as cidades no dropdown
xml_cidades.find("cidade").each( function(){
//graças ao encadeamento, criamos um elemento gastando apenas uma linha (tudo bem, quebrada para melhorar a leitura).
var nOption = $( document.createElement( "option" ) )
.val( $( this ).attr( "cdg" ) )
.append( this.childNodes[0].nodeValue );

cidades.append(nOption);
});
$("#loading").hide("slow");//esconde o carregando...
}


Simples, não?

Agora temos um dos processos mais utilizados hoje em dia, em apenas alguns minutos de códigos.

Então é isso, aproveite a biblioteca e crie outras brincadeiras, mas não esqueça de mostrar pra gente hein? :)

Até a próxima.

Marcadores: , ,

0 Comentários:

Postar um comentário

Assinar Postar comentários [Atom]

<< Página inicial