Olá a todos!
Tenho pleno conhecimento que o assunto "Máscaras em JavaScript" já está um pouco batido. Temos vários tópicos sobre isso aqui mesmo no "Laboratório de Scripts", em sua maioria ótimos! Entretanto, não encontrei nenhum que atendesse a todas as minhas necessidades.
O meu principal objetivo era obter um código flexível, que pudesse ser inserido em qualquer campo-texto do formulário, sem a necessidade de ter de ficar alterando o script *.js. O script deveria ficar lá, quietinho, sem sofrer qualquer tipo de alteração caso o usuário quisesse trocar de CPF para CNPJ, ou então criar coisas estranhas como: )!(@&%! ###(*)(%!.
Além disso, eu queria corrigir um bug que está presente em muitas máscaras, que diz respeito à tecla BACKSPACE. Em alguns casos, o seu uso acabava por corromper toda a máscara, desconfigurando todo o campo.
Por isso, resolvi iniciar do zero esse script. Para ser sincero, comecei a desenvolvê-lo no início de 2009, porém por outros motivos abandonei o projeto, esquecendo-o completamente. Contudo, há alguns dias surgiu uma dúvida no fórum em relação ao uso da tecla BACKSPACE, que causava erro de configuração na máscara. Tentei recuperar o backup e hoje, finalmente, terminei o código.
Testei, testei e não encontrei erros. Se alguém encontrar, por favor, envie uma MP para eu editar o tópico, ok?
Aí vai o código de presente:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Máscaras para formulários - by Klonder</title>
</head>
<body>
<script type="text/javascript">
/*
Script desenvolvido por: Klonder
Postagem exclusiva em: http://www.forum.imasters.com.br
Versão 13.01.2010 - 20:05h;
Esse script poderá ser utilizado sem a necessidade de citação do autor.
Entretanto, não diga que o script é de sua autoria, pois o mesmo será postado nesse fórum, com a data precisa da publicação e com o nome do autor ao lado.
A capacidade em respeitar o trabalho do outro mostra o tipo de indivíduo que você realmente é.
*/
var trava = false;
var iCount1, iCount2, iCount, iTexto, nChar;
/*
iCount1 --> Comprimento da máscara no evento onkeydown (Referência para filtrar teclas de aderência!!!);
iCount2 --> Comprimento da máscara no evento onkeyup;
iTexto --> Texto atual na máscara, antes da função mascara() ser chamada com onkeyup;
nChar --> Variável controle;
*/
//Função chamada a partir do evento onkeydown;
function MaskDown(loc) {
if(trava == false) {
//Armazenando a frase em uma variável, para ser utilizada durante o backspace;
iTexto = document.getElementById(loc).value;
//Armazenando a frase em uma variável, para ser utilizada durante adição de caracteres;
objCampoMascara = document.getElementById(loc);
//Comprimento da máscara no evento onkeydown;
iCount1 = objCampoMascara.value.length;
//Adicionando trava para evitar possível tecla de aderência:
trava = true;
}
}
//Função chamada a partir do evento onkeyup;
function MaskUp(loc,msc) {
//Recuperando o local do campo que contém a máscara;
objCampoMascara = document.getElementById(loc);
//Comprimento da máscara no evento onkeyup;
iCount2 = objCampoMascara.value.length;
//Verificando se o usuário inseriu novos caracteres, ou se apertou a tecla DELETE/BACKSPACE:
// -------------------- Caso 1: Inserção de novos caracteres --------------------
//Quantidade caracteres final (onkeydown) maior que a inicial (onkeyup) -> Houve inserção de caracteres;
if (iCount2 > iCount1) {
//Recortando a máscara para filtrar possível tecla de aderência:
objCampoMascara.value = objCampoMascara.value.substr(0,iCount1+1);
//Verificando se o comprimento da máscara não é excedido;
if(objCampoMascara.value.length > msc.length) {
objCampoMascara.value = objCampoMascara.value.substr(0,msc.length);
}
//Antes de mais nada, verificar se a máscara já inicia com caracteres especiais e já inserí-los;
if(iCount1 == 0) {
//Contando o número de caracteres especiais (se porventura existirem):
if (msc.substring(iCount1,iCount1+1) != "#") {
nChar=1;
//Contar as ocorrências de símbolos especiais, diferentes de: #, que iniciam a máscara:
while (msc.substring(iCount1+nChar,iCount1+nChar+1) != "#" && nChar <= msc.length) {
nChar++;
}
objCampoMascara.value = msc.substring(0,iCount1+nChar) + objCampoMascara.value.substr(0,iCount1+1);
}
//Se não iniciar com caracteres especiais:
} else {
//Verificando se existe caracteres especiais à frente do último caractere inserido:
if (msc.substring(iCount1+1,iCount1+2) != "#") {
var nChar=1;
//Contar as ocorrências de símbolos especiais que sucedem o último caractere inserido;
while (msc.substring(iCount1+nChar,iCount1+nChar+1) != "#" && nChar <= msc.length) {
nChar++;
}
objCampoMascara.value = objCampoMascara.value.substr(0,iCount1+1) + msc.substring(iCount1+1,iCount1+nChar);
}
}
// -------------------- Caso 2: Deleção de caracteres | Backspace --------------------
} else {
//Verificando se o caractere apagado é um símbolo especial ou não:
if (msc.substr(iCount2,1) != "#") {
nChar = 1;
//Looping para percorrer os caracteres especiais retrocedentes:
while (msc.substring(iCount1-nChar,iCount1-nChar-1) != "#" && nChar <= iTexto.length) {
nChar++;
}
//Apagando os caracteres retrocedentes, conforme o valor atribuído a nChar:
objCampoMascara.value = iTexto.substr(0,iCount2-nChar);
} /*else {
//Recortando a máscara para filtrar possível tecla de aderência: Default: desabilitado.
objCampoMascara.value = iTexto.substr(0,iCount1-1);
}*/
}
//Liberando a trava para possibilitar novo evento onkeydown:
trava = false;
}
</script>
Telefone: <input type="text" id="t1" onkeydown="MaskDown('t1')" onkeyup="MaskUp('t1','(##) ####-####')"> (##) ####-####
<br>Data: <input type="text" id="t2" onkeydown="MaskDown('t2')" onkeyup="MaskUp('t2','##/##/####')"> ##/##/####
<br>CEP: <input type="text" id="t3" onkeydown="MaskDown('t3')" onkeyup="MaskUp('t3','#####-###')"> #####-###
<br>CPF: <input type="text" id="t4" onkeydown="MaskDown('t4')" onkeyup="MaskUp('t4','###.###.###-##')"> ###.###.###-##
<br>CNPJ: <input type="text" id="t5" onkeydown="MaskDown('t5')" onkeyup="MaskUp('t5','##.###.###/####-##')"> ##.###.###/####-##
<br>Placas de automóveis: <input type="text" id="t6" onkeydown="MaskDown('t6')" onkeyup="MaskUp('t6','### ####')"> ### #####
<br><br>Aleatório 1: <input type="text" id="t7" onkeydown="MaskDown('t7')" onkeyup="MaskUp('t7','|$-% *& «##» .:. «##» (###) %-$|')" size="40"> |$-% *& «##» .:. «##» (###) %-$|
<br><br>Aleatório 2: <input type="text" id="t8" onkeydown="MaskDown('t8')" onkeyup="MaskUp('t8','<--| ##.### |-->')" size="40"> <--| ##.### |-->
<br><br><br><br>Características principais:
<br>1. Filtro para evitar teclas de aderência;
<br>2. Flexibilidade para qualquer tipo de máscara, com qualquer tipo de caractere especial;
<br>3. Permite correção inteligente quando BACKSPACE for pressionado;
<br>4. Permite o uso de símbolos especiais em sequência, inclusive com espaço;
<br>5. Controlam a quantidade de símbolos na máscara, não havendo necessidade de inserir o "maxlength" em cada um dos campos de texto que forem criados (o "maxlength" pode ser usado a critério do desenvolvedor).
<br>6. Código-fonte reaproveitável para qualquer campo texto do formulário.
<br>7. Código-fonte comentado, para melhor compreensão do processo.
</body>
</html>
Espero que gostem!
Abraços a todos usuários e visitantes do fórum! http://forum.imasters.com.br/public/style_emoticons/default/natal_biggrin.gif