Artigos de JQuery.



JQuery e AJAX – Combo de Estado e Cidade

Essa semana precisei implementar uma solu√ß√£o de combo din√Ęmico de Estado / Cidade que carregasse as op√ß√Ķes das cidades de acordo com a escolha do estado. Obviamente teria que usar Ajax (JQuery) e o Json (JavaScript Object Notation) que √© um formato leve de troca de dados (fonte: http://www.json.org/).

Fiz uma pesquisa r√°pida na NET e de cara encontrei um excelente artigo de Davi Ferreira: “Populando selects de cidades e estados com AJAX (PHP e jQuery)” (http://www.daviferreira.com/posts/populando-selects-de-cidades-e-estados-com-ajax-php-e-jquery). No entanto para o meu caso a solu√ß√£o do Davi teria que ser reinventada tendo em vista que no meu form haviam 3 conjuntos de Estado/Cidade. Um para os dados de endere√ßo do usu√°rio e outros dois para os dados profissionais. Uma op√ß√£o seria repetir o c√≥digo 3 vezes, uma para cada conjunto, o que n√£o √© nada elegante.

A op√ß√£o foi portanto, criar uma fun√ß√£o dentro do Javascript que fizesse o trabalho sujo de forma din√Ęmica. Ao inv√©s de criar uma fun√ß√£o JS que aproveitasse o JQuery, segui a sugest√£o do Basil Godman, “Definindo suas pr√≥prias fun√ß√Ķes com o JQuery” (http://blogs.microsoft.co.il/blogs/basil/archive/2008/09/22/defining-your-own-functions-in-jquery.aspx) e criei uma fun√ß√£o do pr√≥prio JQuery.

Outra coisa que fiz tamb√©m foi retirar o campo de “span” est√°tico com a mensagem “Carregando …” como sugere o Davi. Ela agora aparece de forma din√Ęmica dentro da pr√≥pria fun√ß√£o. Facilitando a manuten√ß√£o, inclus√£o de em gif animado, uma classe espec√≠fica e despoluindo o HTML, imagina isso para 4 ou 5 campos Estado/Cidade!

Abaixo você poderá baixar o código completo inclusive com o DDL e o DML do MySQL, além de verificar os 4 arquivos necessários para que tudo funcione comentados.

Arquivos completos para download

Arquivo de conex√£o com o Banco
[php]$con = mysql_connect( ‘localhost’, ‘root’, ” ) ;
mysql_select_db( ‘cadastro’, $con );[/php]

O PHP e o HTML dos Selects
[sourcecode language=”html”]<?php
require("conn.open.php");

function listaEstadosOrderIdAsc(){
return mysql_query("SELECT cod_estados, sigla FROM estados ORDER BY sigla ASC");
}
?>
<p>
<label for="cod_estados">Estado:</label>
<select name="cod_estados" id="cod_estados">
<option value="">(selecione aqui)</option>
<?php $estados = listaEstadosOrderIdAsc(); while ($row = mysql_fetch_object($estados)) { ?>
<option value="<?php echo $row->cod_estados; ?>"><?php echo $row->sigla; ?></option>
<?php } ?>
</select>
<label for="cod_cidades">Cidade:</label>
<select name="cod_cidades" id="cod_cidades">
<option value="">– Escolha um estado –</option>
</select>
</p>
[/sourcecode]

Aqui a função JQuery propriamente dita, comentada para facilitar o entendimento.

[sourcecode language=”javascript”]
$(document).ready(function(){

// Por Rogerio Coli, www.rcoli.com.br – favor n√£o remover
jQuery.fn.carregaCidades = function() {

// Objeto que guarda os argumentos
var args = arguments[0] || {};

//id do Select de Cidades
var idSelectCidade = args.idSelectCidade;

// P√°gina que ir√° criar o JSon
var paginaPhpCidades = ‘cidades.ajax.php’;

// Conte√ļdo do elemento span que vai aparecer enquanto carregam as cidades,
// pode ser substituído por uma imagem. Coloque a tag completa
var carregandoMsg = ‘Aguarde, carregando…’

// Classe do elemento span que vai aparecer enquanto carregam as cidades
var carregandoClass = ‘class’;
// após as cidades carregarem aparece esta mensagem
var jsonPrimeiroElemento = ‘(selecione a cidade)’;
// Aqui eu pego a frase do primeiro option de Cidade
var primeiroElemento = $(idSelectCidade).find(‘option:first’).html();

if( $(this).val() ) {
// escondendo as cidades até carregarem
$(idSelectCidade).hide();
// mensagem de espera: carregando
$(idSelectCidade).after(‘<span class=’+ carregandoClass +’>’+carregandoMsg+'</span>’);

$.getJSON(paginaPhpCidades+’?search=’,{cod_estados: $(this).val(), ajax: ‘true’}, function(j){
// √Č importante que o value seja vazio pra que o formul√°rio n√£o seja enviado vazio
// caso use o form validate
var options = ‘<option value="">’+jsonPrimeiroElemento+'</option>’;
for (var i = 0; i < j.length; i++) {
// √Č importante que o value seja vazio pra que o formul√°rio n√£o seja enviado vazio
// caso use o form validate
options += ‘<option value="’ + j[i].cod_cidades + ‘">’ + j[i].nome + ‘</option>’;
}
// mostrando as cidades após carregarem e removendo a mensagem de espera
$(idSelectCidade).html(options).show();
$(idSelectCidade).next().remove();
});
} else {
$(idSelectCidade).html(‘<option value="">’+primeiroElemento+'</option>’);
}

};
//Inciando o SELECT, importante ao recarregar a p√°gina
$("#cod_estados option:first").attr(‘selected’,’selected’);
// Aqui eu chamo a função e o método que irá carregá-la
$(‘#cod_estados’).change(function(){ $(this).carregaCidades({idSelectCidade: ‘#cod_cidades’}); })
});
[/sourcecode]

O Arquivo AJAX que monta o JSon

[sourcecode language=”php”]
header( ‘Cache-Control: no-cache’ );
header( ‘Content-type: application/xml; charset="utf-8"’, true );

require("conn.open.php");

$cod_estados = mysql_real_escape_string( $_REQUEST[‘cod_estados’] );

$cidades = array();

$sql = "SELECT cod_cidades, nome
FROM cidades
WHERE estados_cod_estados=$cod_estados
ORDER BY nome";
$res = mysql_query( $sql );
while ( $row = mysql_fetch_assoc( $res ) ) {
$cidades[] = array(
‘cod_cidades’ => $row[‘cod_cidades’],
‘nome’ => htmlentities($row[‘nome’]),
);
}

echo( json_encode( $cidades ) );

[/sourcecode]

JQuery Form Validation РValidação de Datas no Google Chrome

Recentemente me deparei com um BUG ser√≠ssimo do plugin do JQuery, form validation. O campo “data:true” do jQuery Validation Plugin 1.9.0 aceita o formato de data em portugu√™s (ex: 31/12/2011) em todos os navegadores exceto o Google Chrome (15.0.874.121 m, no momento desse artigo) e possivelmente no Safari, de acordo com algumas reclama√ß√Ķes de outros programadores com o mesmo problema.

Ao tentar buscar alternativas de contornar o problema eu percebi que havia uma funcionalidade j√° desenvolvida para a valida√ß√£o de data no formato DE (alem√£o,”29.04.1994″ ou “1.1.2006”), bastante semelhante ao padr√£o brasileiro. S√≥ que essa fun√ß√£o n√£o aparece no arquivo dispon√≠vel para o download, ou foi retirada posteriormente como pode ser visto no reposit√≥rio do GitHub do plugin. Sendo que na linha 275 (messages) alguns arquivos do site do plugin ainda fazem refer√™ncia a tal fun√ß√£o: “dateDE”.

Para normalizar a situa√ß√£o eu sugiro incluir algumas linhas de c√≥digo no seu “jquery.validate.js”, vamos a elas:

Procure nas linhas 268/275 dentro de messages aonde aparece a mensagem de data e coloque abaixo de date a linha destacada:
[sourcecode language=”javascript” highlight=”8″]
messages: {
required: "Campo obrigat&oacute;rio.",
remote: "Por favor revise este campo.",
email: "Por favor digite um e-mail v&aacute;lido.",
url: "Por favor digite uma URL v&aacute;lida.",
date: "Por favor digite uma data v&aacute;lida.",
dateISO: "Por favor digite uma data v&aacute;lida (ISO).",
dateDE: "Por favor digite uma data v&aacute;lida (DE, BR).",
number: "Por favor digite um n√ļmero v&aacute;lido.",
digits: "Por favor digite somente n√ļmeros.",
creditcard: "Por favor digite um cartão de crédito v&aacute;lido.",
equalTo: "Por favor digite o mesmo valor.",
accept: "Por favor digite um valor com uma extens√£o v&aacute;lida.",
maxlength: $.validator.format("Por favor digite mais de {0} caracteres."),
minlength: $.validator.format("Por favor digite pelo menos {0} caracteres."),
rangelength:$.validator.format("Por favor digite um valor entre {0} e {1} caracteres."),
range: $.validator.format("Por favor digite um valor entre {0} e {1}."),
max: $.validator.format("Por favor digite um valor menor ou igual a {0}."),
min: $.validator.format("Por favor digite um valor maior ou igual a {0}.")
},
[/sourcecode]

Em seguida ache a função dateISO lá pela linha 1050 e insira a a função abaixo. Atente que há a função original e a alterada
[sourcecode language=”javascript”]
// //http://docs.jquery.com/Plugins/Validation/Methods/dateDE
dateDE:function(value,element){
// Original DE
//return this.optional(element)||/^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
// Oposite ISO
return this.optional(element)||/^\d{1,2}[\/-]\d{1,2}[\/-]\d{4}$/.test(value);
},
[/sourcecode]
Agora é só fazer a chamada normalmente em sua validação:
[sourcecode language=”javascript”]
$("#form").validate({
rules:
{
data_nascimento: { required:true, minlength: 10, dateDE:true },
}
});
[/sourcecode]

Atente que esta validação não verifica se é uma data válida, somente se atende a um formato específico. Para a validação de uma data válida (meses com 30 ou 31 dias, anos bissextos e etc) é necessário
extender as funcionalidades do plugin. Em breve farei isso, até lá.

Assine o RSS de meus Artigos e Comentários.