Vou tentar, uma vez por semana, responder aqui a alguma dúvida de algum aluno dos cursos da Visie que seja útil para todo mundo. A de hoje:
Javascript: máscara em campos de formulário simples e crossbrowser:
Uma dúvida muito comum diz respeito ao tratamento de teclas para campos de formulário. É um hábito de programadores de sistemas Desktop filtrar o que o usuário digita em campos como, por exemplo, data e CPF, permitindo apenas que ele digite número, e colocando automaticamente pontos, traços e outros separadores conforme ele digita. Ao tentar reproduzir esse comportamento na web, a experiência pode ser um tanto quanto frustrante, principalmente devido às diferenças entre o Internet Explorer e os outros navegadores. Além disso, a captura de eventos de teclado em Javascript é uma tarefa relativamente complicada. Por isso vou apresentar uma técnica alternativa, que não usa a captura de teclas.
Comentários aqui.
53 Comentários
53 Comentários
Fernando André 19/01/2007 às 17:29
Boa Elcio, gostei da iniciativa! Vai ajudar bastante gente inclusive eu! Valeu
Lucio Libanori 19/01/2007 às 17:44
Ótimo artigo, Elcio. Muito útil.
Bruno 19/01/2007 às 20:33
Não gosto muito de mascaras na web… pq elas nunca funcionam direito. Se vc erra um dado e tenta corrigir sempre acaba dando alguma meleca…
De qualquer forma acho que para usuários mais dummies acaba sendo válido…
Vedovelli 19/01/2007 às 23:50
Elcio, muito bom como sempre! Ainda ontem cansei a beleza procurando por um script para mascarar campos como cpf, cnpj, telefone etc. Consegui um que funciona com FF e IE porém ele é muito extenso. Sua solução é bem enxuta e vai me ajudar muito! Mas cá entre nós: regex é complicado demais! Vc tem aí alguns bons links onde o assunto é explicado mais detalhadamente?
Abração!
Ved
Reginaldo Sousa 20/01/2007 às 01:55
Muito boa cara.
Eu já até fazia esses tipos de criticas, mas de uma maneira um pouco diferente.
Adriano 20/01/2007 às 08:58
Muito bom o artigo/tutorial e parabéns pela iniciativa…
Junio Vitorino 20/01/2007 às 20:34
Boa, boa mesmo…
poste9 21/01/2007 às 22:47
Muito bom artigo.
O único probleme que ví é no evento de captura que poderia ser trocado já que neste evento algumas teclas não são capturadas e isso pode tirar um pouco da eficiencia do “filtro”.
Só isso mesmo, no mais nota 10!
*: Evento usado: onkeypress
*: Evento sugerido: onkeydown
Erick Wilder 23/01/2007 às 17:39
Infelizmente na maior parte das situações não temos escolha a não ser empurrar uma másca de campo. Não sou a favor de marcarar os campos e apoio plenamente a idéia de instruir o usuário de como informar os dados utilizando pequenas legendas próximo aos campos.
Ultimamente tenho olhado as questões de acessibilidade e usabilidade com mais seriedade e adicionando seus valores na produção do trabalho e por isso só tenho que discordar do exemplo em que se separa o campo de telefone em pedaços. Isso nos “obriga” a escrever mais um pouco de javascript para mudar o foco do campo ao atingir o limite de caracteres. Tá!! Isso não é nada de outro mundo, mas a questão é que se não fazemos isso, ou isso não funciona, o usuário pode ficar realmente frustrado, pois, digitou o número do telefone completo e terá de repetir tudo novamente.
Ninguém gosta de preencher formulário, preencher 2 veze o mesmo campo é simplesmente irritante.
Sou mais a favor do tratamento e manipulação dos dados no servidor. Validar um telefone (inclusive utilizando expressões regulares) é muito mais eficaz e trás menos desconforto ao usuário quando se faz de modo tranparente, sem dar ao usuário a preocupação com “como eu devo informar o CPF?? Com ponto ou sem ponto? e o hifen o que faço com ele?”.
O usuário não é obrigado a saber como o sistema funciona, ele apenas quer usá-lo e forçá-lo a fazer o SEU trabalho pode ser muito chato. mas, como disse nem sempre é a nossa opinião que conta e sim a de quem está pagando.
andre 28/01/2007 às 11:46
Caro amigo.
Eu estou com um problema, pois estou começando em java script e na minha opinião vc arrebentou na explicaçao, porém eu estou com algmas dificuldades.
na funçao replace tem uns caracteres que pelo que sei são de formataçao, replace(/o/gi e etc…. eu nao sei nenhum, será que vc poderia me disponibilizar algum material?Uma tabela???sei lá
wc 28/01/2007 às 20:54
Nota 10
camilo 31/01/2007 às 13:54
Gostei, realmente útil. Infelizmente há muitos problemas no uso de máscaras (eu mesmo já passei maus bocados por causa dessas mascaras….), tanto que escolho pela primeira alternativa, a de ser específico nos rótulos e simbolos, tornando menos problemática a navegação. É ruim quando erramos, mas acho horrivel quando uma máquina diz que estou errado… enfim, muito bom, útil, o código também está bem limpo, gostei muito da forma que a função foi escrita… abraço
André Luiz 31/01/2007 às 17:25
Muito bom esse seu script mascara. Deu uma força danada no sisteminha que eu estou fazendo. Parabéns. Qualquer coisa se precisar de uma força pode contar comigo. Grande Abraço (:
Robson Pinto 08/02/2007 às 14:23
Achei muito interessante esse código, vou até aproveitá-lo para implementar junto com a framework jQuery, só um detalhe que eu vou rever quando eu programar é que o campo CEP está aceitando hífens ao longo do campo, esse deveria ser excluso assim como nos campos CPF e TELEFONE por exemplo
Maicon 01/03/2007 às 20:49
Nota 10 mesmo, so gostaria de saber como fazer uma funcao para formatar um campo de valor??
p ficar por exemplo: 2.456,56
Bernardo 07/03/2007 às 12:47
Ótima iniciativa! Gostei tanto que quis implementar, mas tive problemas…
Tanto no IE (7) quanto no Firefox (2) deu erro de script. Observando o erro pelo Firebug, ele me retorna a seguinte mensagem:
v_fun is not a function
execmascara()
[Break on this error] v_obj.value=v_fun(v_obj.value)
Então mudei o código de:
function mascara(o,f){v_obj=o
v_fun=f
setTimeout("execmascara()",1)
}
para:
function mascara(o,f){v_obj=o
v_fun=f
// setTimeout("execmascara()",1)
v_obj.value=v_fun(v_obj.value)
}
e me retorna o erro:
v_fun is not a function
mascara(input#cpf 0, input#cpf 0)
onkeypress(keypress charCode=48, keyCode=0)
[Break on this error] v_obj.value=v_fun(v_obj.value)
Não estou sabendo resolver o problema, se o Élcio ou alguém quiser tentar resolver, já vou agradecendo!
Abraços!
andre luiz 08/03/2007 às 13:22
O script está com alguns bugs com as teclas delete e backspace
francis 09/03/2007 às 16:30
usei o exemplo que deixou em uma pagina em branco e funcionou, mas quando fui adaptar para uma pagina que ja tinha um codigo pronto na esta funcionando! o q fiz de errado? alguem pode me ajudar! nao sei se tem algum problema o fato do meu codigo ja possuir outros codigos java script
acessem:www.monitorvirtual.com/incluiraluno.php
Richard Venâncio Vasco 07/06/2007 às 14:18
Elcio, fico ótimo cara VLW.
Bernardo>>>
É provavel que na chamada da função você ta colocando assim:
onkeypress="mascara(this,'telefone')"
// o correto é assim:
onkeypress="mascara(this,telefone)"
André Luiz>>>
O backSpace e o delete não são reconhecidos no evendo onkeypress, tenta colocar onkeydown
Bom galéra, tive necessidade de outras mascaras e segue abaixo o código:
function data(v){
v=v.replace(/\D/g,"") //Remove tudo o que não é dígito
v=v.replace(/(\d{2})(\d)/,"$1/$2") //Coloca barra entre o segundo e o terceiro digito
v=v.replace(/(\d{2})(\d)/,"$1/$2") //Coloca barra entre o quinto e o sexto digito
return v
}
function valor(v){
v=v.replace(/\D/g,"") //Remove tudo o que não é dígito
v=v.replace(/(\d)(\d{2})$/,"$1.$2") //Coloca ponto antes dos 2 últimos digitos
return v
}
Richard Venâncio Vasco 07/06/2007 às 14:31
PS: A function valor deve ser chamada no evento onkeydown
Rô 07/06/2007 às 21:27
Brigadá…mtuuuu obrigadáá…
Salvou minha nota di Aplicativos para Internet!
BrigadÁ msm! ^^
bjuu
Augusto Barbosa 20/08/2007 às 10:08
Bernardo, tive o mesmo problema e percebi que acontecia quando eu usava um id igual ao nome do parâmetro da função. Resolvi mudando o nome do id. (como usado no exemplo: icpf, icep, itelefone, etc.)
Queli 21/08/2007 às 19:11
Achei ótimo este código para máscaras, passei o dia procurando algo parecido mas só encontrei a solução perfeita aqui. Eu realmente não entendo nada de Javascript, mas em alguns casos ele se faz necessário. Só tive um problema ao implementar o script, ele não está rodando nas minhas páginas caso eu coloque a tag . Reparei também que aqui no código fonte do artigo não há o .
Alguma sugestão?
Queli 21/08/2007 às 19:13
Achei ótimo este código para máscaras, passei o dia procurando algo parecido mas só encontrei a solução perfeita aqui. Eu realmente não entendo nada de Javascript, mas em alguns casos ele se faz necessário. Só tive um problema ao implementar o script, ele não está rodando nas minhas páginas caso eu coloque a tag
. Reparei também que aqui no código fonte do artigo não há o.Alguma sugestão?
Jaqueline 03/10/2007 às 16:13
eu queria fazer uma validacao onde eu só pudesse entrar com numeros e pontos….
nao consigo fazer..
alguem pode ajudar?
Adorei as mascaras, foram muito uteis..
Kleiton 04/10/2007 às 16:21
Ultilizei para ultilizar no campo do formulario de um livro ISBN onde seria neste formato:
123-12-12345-12-1
…consegui
Mas preciso que permita “Letras”, não apenas numeros…alguém pode me ajudar?
flow t+
function cpf(v){
v=v.replace(/\D/g,”")
v=v.replace(/(\d{12})(\d{1})/,”$1-$2″)
v=v.replace(/(\d{10})(\d)/,”$1-$2″)
v=v.replace(/(\d{5})(\d)/,”$1-$2″)
v=v.replace(/(\d{3})(\d{2})/,”$1-$2″)
return v
}
Cleiton da Silva 05/10/2007 às 16:20
Obrigado mesmo cara, graças a iniciativas de caras como vc que temos a web tão dinâmica e acessível.
Continue assim!
Joao Lemos 18/10/2007 às 09:32
Elcio,
excelente esse código de máscaras, serviu como uma luva. Foi somente copiar e colar, simples, pŕatico e objetivo!!!
Parabésn!!!
Ricardo Rodh 22/11/2007 às 23:58
Uma coisa que facilitou no uso do script para vários campos foi o seguinte:
Coloquei o maxLength diretamente no código de cada campo.
Exemplo:
function telefone(v){
document.getElementById(v_obj.name).maxLength=14
v=v.replace(/\D/g,"") //Remove tudo o que não é dígito
v=v.replace(/^(\d\d)(\d)/g,"($1) $2") //Coloca parênteses em volta dos dois primeiros dígitos
v=v.replace(/(\d{4})(\d)/,"$1-$2") //Coloca hífen entre o quarto e o quinto dígitos
return v
}
Assim limpa o código HTML
Parabéns pelo código.
Raphael Azeredo 01/12/2007 às 20:24
Elcio excelente material, porém estou com um problema com o IE, estou utilizando essa mascara para um formulário, e em um formulário utilizamos o atributo name nos campos de input para pegar o valor desses campos, porem no meu IE quando utilizo a mascara e coloco o atributo name no input a mascara não funciona ja no FF ja funciona, sabe como posso resolver esse problema no IE?
Diego 06/12/2007 às 11:38
Como eu posso fazer um que só todos os caracteres menos os especiais tipo acentos e operadores…? Existe aguma coisa tipo o v=v.replace(/\D/g,”") que deixa somente os nros ?
valeu
Pedro 30/01/2008 às 11:50
Utilizamos seu javascript aqui: http://www.symfonybr.com/2008/01/14/helper-do-symfony-para-fazer-mascaras-de-campos-input-2/
Valeu!!
Joao Lemos 05/02/2008 às 11:56
O script não funciona se o nome do campo é o mesmo do nome da função. Exemplo: <input type=”text” id=”cep” name=”cep” value=”{cep}” onkeydown=”mascara(this,cep)”
Prá funcionar mudei o nome da função para mcep, ficando assim: <input type=”text” id=”cep” name=”cep” value=”{cep}” onkeydown=”mascara(this,mcep)”
Estou usando o navegador web do gnome.
[]s
Geraldo Cardoso 23/03/2008 às 06:37
Elcio,
Uma solução simple e elegante. Meus parabens. Só tenho uma duvida: quando uso codigo dentro da propria pagina funciona mas se coloco dentro de um arquivo dá erro. Ex. ‘telefone’ não definido
Poderia me ajudar ? O que falta ser feito ?
Flávio 10/04/2008 às 17:27
Os script’s são bons….. ja usei o de data, cep, cnpj, cpf, só números…..
Muito Bom
Parabens
Juliana 17/07/2008 às 17:13
estou tentando usar a máscara de só numeros, mas não está funcionando, será que pode me auxiliar?
Tamiris 21/08/2008 às 14:56
Parabens! Algo muito útil e o mais importante, funciona.. pq muitas vezes perdemos muuuuito tempo procurando estes scripts e a maioria deles não funciona…
Prabens mesmo!
Tiago Luis Facco 03/10/2008 às 15:51
Olá Elcio, gostei muito desse seu artigo e me foi muito útil. Deixo aqui uma dica para validar data de nascimento que fiz com a ajuda de seu script:
function dataNascimento(v) {
v=v.replace(/\D/g,”");
v=v.replace(/^(\d{2})(\d{2})(\d)/,”$1/$2/$3″);
return v;
}
Grande abraço! T+
Diego 07/10/2008 às 20:52
Faltou a barra invertida antes do “D” na função do CEP.
function v_cep(v){
v=v.replace(/\D/g,"") //Remove tudo o que não é dígito
v=v.replace(/^(\d{5})(\d)/,"$1-$2") //Esse é tão fácil que não merece explicações
return v
}
Herbert 13/11/2008 às 15:49
Acho muito prático essas mascaras, as utilizo em alguns sistemas que desenvolvi.
Só falta uma mascara para campos do timo moeda… hauahuah
tentei emplementar sozinho mas não consegui!
seria interessante uma mascara que colocasse a “,” antes dos dois últimos dígitos!
Lucas Felix 23/12/2008 às 11:33
Segue a função para valores monetários
function Valor(v){
v=v.replace(/\D/g,”") //Remove tudo o que não é dígito
v=v.replace(/(\d+)(\d{2})/,”$1,$2″) //Insere a vírgula
v=v.replace(/(\d+)(\d{3},\d{2})$/g,”$1.$2″); //Coloca o primeiro ponto
var qtdLoop = (v.length-3)/3;
var count = 0;
while (qtdLoop > count)
{
count++;
v=v.replace(/(\d+)(\d{3}.*)/,”$1.$2″); //Coloca o resto dos pontos
}
v=v.replace(/^(0+)(\d)/g,”$2″); //remove “0″ à esquerda
return v
}
Gilvan P.S 08/01/2009 às 16:06
Cara muito bom esse artigo me ajudou muito..
Tks…..
Fernando 19/01/2009 às 15:46
Essas funções não funcionam quando estão dentro de um , com excessão da função soNumeros. Exemplo de código que não funciona:
Se tirar o form funciona normal, alguém sabe como resolver?
Abraços.
Fernando 19/01/2009 às 15:49
Essas funções não funcionam quando estão dentro de um , com excessão da função soNumeros. Exemplo de código que não funciona:
Se tirar o form funciona normal, alguém sabe como resolver?
Abraços.
sombriks 30/01/2009 às 21:16
véio gostei das máscaras.
aqui eu não coloco os eventos no html, eu “appendo” eles com DOM vl2, daí, se eu quiser um campo com máscara de números fica mais ou menos assim:
var campo = new FildNumerico(document.getElementById(”campo”))
e pronto, o campo é numérico.
claro, essa função FildNumerico internamente é mais ou menos assim:
function FildNumerico(fild){
function soNumeros(v){
return v.replace(/\D/g,”")
}
function aplicar(){
fild.value = soNumeros(fild.value)
}
if(document.addEventListener){
fild.addEventListener(”keypress”,function(evt){
setTimeout(aplicar,1)
},true)
}else if (document.attachEvent){//msIE
fild.attachEvent(”onkeypress”,function(evt){
setTimeout(aplicar,1)
})
}
return fild
}
“classe” essa que não seria possível sem essa lógica original, que faz a parte pesada,
Sued Jorge Nassar 11/03/2009 às 15:32
Grande Elcio!
Primeiramente, quero agradecer por este tutorial. Salvou muitos dias…
“Segundamente” gostaria de contribuir com ajunção das mascaras de cpf e CNPJ numa só. Formata com CPF até o undécimo dígito. Se digitar mais de 11, “tumaticamente” formata para CNPF. Facilita quando existem as duas possibilidades de entrada. O campo deve ter tamanho máximo de 18 caracteres. Pode ajudar.
Abraços
function masccnpjcpf(v){
v=v.replace(/\D/g,”") //Remove tudo o que não é dígito
if (v.length<=11) // aqui verifica quantos digitos
{
v=v.replace(/(\d{3})(\d)/,”$1.$2″) //Coloca um ponto entre o terceiro eo quarto dígitos
v=v.replace(/(\d{3})(\d)/,”$1.$2″) //Coloca um ponto entre o terceiro e quarto dígitos
//de novo (para o segundo bloco de números)
v=v.replace(/(\d{3})(\d{1,2})$/,”$1-$2″) //Coloca um hífen entre o terceiro e o quarto dígitos
}
else
{
v=v.replace(/\D/g,”") //Remove tudo o que não é dígito
v=v.replace(/^(\d{2})(\d)/,”$1.$2″) //Coloca ponto entre o segundoe o terceiro d
v=v.replace(/^(\d{2})\.(\d{3})(\d)/,”$1.$2.$3″) //Coloca ponto entre o quinto o sexto dígitos
v=v.replace(/\.(\d{3})(\d)/,”.$1/$2″) //Coloca uma barra entre o oitavo e o nono dígitos
v=v.replace(/(\d{4})(\d)/,”$1-$2″) //Coloca um hífen depois do oco de quatro dígitos
}
return v
}
Eduardo 07/04/2009 às 10:34
Cara as funções são muito boas.. , me ajudaram a criar uma para data, abraços…
Gerson 17/04/2009 às 13:03
gostei meu caro. Muito bom.
Luiz Carlos 02/05/2009 às 03:01
Prezado Elcio,
Encontrei vários artigos muito bons para o tatamento de mascaras para campos, mas o seu, meu caro, pela sua excelência, objetividade e simplicidade, nos deixa sem palavras para expressar elogios.
Parabéns pelo artigo.
Parabéns por este dom .
Ramon 13/05/2009 às 11:54
me ajudou muito.. vlw mesmo cara!
Roger W. Barros 13/06/2009 às 03:43
Olá amigos.. a tempos que tento entender essas expressões regulares e não tem jeito, não entra na minha cabeça.
Eu preciso muito uma funçãozinha dessas pra formatar valores dessa maneira:
entrada ex.:
1222333
mascara:
R$ 1.222.333,00
Se alguém conseguir tirar esse fantasma da minha vida eu agradeço muuuuuiitooo!!! husauhsa
valeu!
Roger W. Barros 13/06/2009 às 15:50
me encarnei nos exeplos dados aki e consegui fazer!!!!!
Já vou contribuir com uma mascara pra moeda!
function moeda(v) {
v=v.replace(/(\,\d{1,2})/,”"); // Remove “,??” (normalmente “,00″) no final para não atrapalhar
v=v.replace(/\D/g,”"); // Remove tudo o que não é dígito
v=v.replace(/^(0+)(\d)/g,”$2″); // Remove zeros à esquerda
v=v.replace(/(\d)(\d{3})$/,”$1.$2″); // Coloca um ponto entre o último e o penultimo bloco de 3 digitos
v=v.replace(/(\d)(\d{3}\.)/,”$1.$2″); // Após último bloco de 3 digitos substitui “????.” por “?.???.”
v=v.replace(/(\d)(\d{3}\.)/,”$1.$2″); // Após penultimo bloco de 3 digitos substitui “????.” por “?.???.”
v=v.replace(/^(\d)/g,”R$ $1″); // Coloca “R$ ” no começo
v=v.replace(/(\d{1,})$/,”$1,00″); // Coloca “,00″ no final
return v;
}
formata até 999 bilhões. para mais é só duplicar o código da 5ª linha.
ex.:
999999999999
fica assim:
R$ 999.999.999.999,00
Elcio Ferreira 16/06/2009 às 09:07
Excelente código, Roger! Obrigado por compartilhar. Adaptei para funcionar com centavos e formatar valores maiores:
function moeda(v) { v=v.replace(/\,0+$/,"") // Remove ,00 do final v=v.replace(/[^\d,]/g,"") // Remove tudo que não é dígito ou vírgula v=v.replace(/^0+/g,"") // Remove zeros à esquerda if(v.indexOf(",")+1){ v=v.replace(/(,\d)$/,"$10") // 2,5 se torna 2,50 }else{ v+=",00" // Acrescenta ,00 ao final dos inteiros } for(var i=0;i<10;i++) v=v.replace(/(\d)(\d{3}[\.,])/,"$1.$2") // Separador de milhar v="R$ "+v // R$ no começo return v; }