Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Fiz uma função básica pra mascarar uma data, mas quando tento apagar o form ele trava no '/', segue o code:
<html>
<head>
<title>Mascara data formulario</title>
<script type="text/javascript">
function mascaraData(campoData)
{
var data = campoData.value;
if(data.length == 2)
{
data += '/';
document.forms[0].data.value = data;
return true;
}
if(data.length == 5)
{
data += '/';
document.forms[0].data.value = data;
return true;
}
}
</script>
</head>
<body>
<form>
<input type="text" name="data" onKeyUp="mascaraData(this);" maxlength="10">
</form>
</body>
</html>Não sou intimo da sintaxe de ER em javascript, teria algum material para indicar? Grato.
links:
http://forum.imasters.com.br/index.php?/topic/331485-expressoes-regulares-em-javascript/
http://guia-er.sourceforge.net/
conseguiu usar a máscara?
já tem uma para datas implementada
Data: <input type="text" name="data" onkeypress="mascara( this, mdata );" maxlength="10" />
<br />Não estou focado em RegExp no momento e não quero usar a máscara por usar, quero entender como funciona.
Qual seria a forma de resolver este problema?
tá... vamos por partes então:
aulinha
o HTML:
<br />
Data: <input type="text" name="data" id="data" onkeypress="mascara(this, mdata);" size="14" maxlength="10" value="" /> é apenas um input normal.
defini o atributo size que é o 'tamanho em caracteres do campo', apenas para ele não ser grande de mais sem necessidade(padrão é 20)
defini o atributo maxlength para 10, pois uma data completa possui 10 digitos: 8 numéricos e 2 barras 00/00/0000
defini o atributo type para text, pois esse é o tipo de input para textos
defini o atributo onkeypress (ao pressionar uma tecla), para chamar uma função que é:
function mascara(o,f){
v_obj=o
v_fun=f
setTimeout("execmascara()",1)
} essa função, não passa de uma interface, para 'atrasar' um pouco(1 milissegundo) a execução da ER, que será chamada através da function execmascara(){
v_obj.value=v_fun(v_obj.value)
}. Pronto, aqui termina a mágica javascript, e vai começar a mágica da Expressão Regular.
O segundo parâmetro da função: mascara(), é a máscara em ER a ser executada, no nosso caso:
function mdata(v){
v=v.replace(/\D/g,""); //Remove tudo o que não é dígito
v=v.replace(/(\d{2})(\d)/,"$1/$2");
v=v.replace(/(\d{2})(\d)/,"$1/$2");
v=v.replace(/(\d{2})(\d{2})$/,"$1$2");
return v;
}destrinchando cada linha, podemos ver que essa função recebe dígito por dígito, caracter por caracter que for sendo colocado no input text pelo usuário, pois invocamos todo o processo no evento onkeypress
Primeira linha:
v=v.replace(/\D/g,""); //Remove tudo o que não é dígito é bem simples.Funciona tudo com o replace() (função nativa da linguagem)
// é a sintaxe para se escrever uma ER, no qual, colocamos nossa expressão dentro dessas 2 barras, e caso precise de algum modificador, após a última
\D significa: não dígito, ou seja, qualquer coisa, que não seja 0,1,2,3,4,5,6,7,8,9
o g final, indica que é global, ou seja, sempre, não importa a posição, se entrar algo que não seja [0-9], o replace age, pois a ER bateu, e ai substitui por 'nada' ( "" )
As demais, linhas usam o conceito de grupo em ER, o primeiro grupo, vai parar no identificador $1, o segundo no $2 e assim por diante.
Um grupo é definido pelos parenteses.
Veja que é no segundo parâmetro da função replace() que colocamos as / , assim como as demais formatações das outras máscaras.
Pois é feito um replace em que
'Quando casar 2 digitos, mande eles pro primeiro grupo'
'Quando casar outros 2 digitos, mande eles pro segundo grupo'
'Agora faça o replace, colocando uma / no meio dos grupos'
E o mesmo segue para as demais.
Acho que não explico muito bem, o link que postei do klonder, ele fala muito bem sobre as ER, vale a pena dar uma olhada.
Veja essa 'meta linguagem' como um auxilio no teu dia-a-dia. Não fará mal nenhum aprender, e muitas outras linguagens usam ER, eu mesmo uso, sempre com php e js.
Se o que eu expliquei a cima, não é suficiente, e você não quer mesmo usar essa boa máscara com ER que funciona, melhor que muitas por ai, dá uma reavaliada no teu script, e veja que o próprio evento onkeyup, é falho, pois posso manter uma tecla pressionada, e assim só chamar a tua função após escrever uns 10 dígitos no campo, além da tua máscara não impedir que eu faça bizarrices como: aa/mm/oque
A tua máscara 'trava' no /, pois você está adicionando o /, verificando apenas a quantidade de caracteres, então toda vez que você apaga, ele recoloca lá, já que o levantar o dedo do botão backspace ou delete tb invoca o evento.
Como eu disse, a solução para a tua função:
identificar se o evento
var kC = (document.all) ? event.keyCode : e.keyCode;não partiu nem do DELETE e nem do BACKSPACE
if( kC!=8 && kC!=46 ) para não executar a máscara nesses 2 botões, pois se não, ela 'trava'.
código para estudo, e melhoria:
<html>
<head>
<title>Mascara data formulario</title>
<script type="text/javascript">
function mascaraData( campo )
{
var data = campo.value;
if( data.length==2 )
{
data += '/';
return data;
}
else if( data.length==5 )
{
data += '/';
return data;
}
else
return data;
}
function id( el ){
return document.getElementById( el );
}
window.onload = function()
{
id('data').onkeypress = function( e )
{
var kC = (document.all) ? event.keyCode : e.keyCode;
if( kC!=8 && kC!=46 )//não chamar a função nem no BACKSPACE e nem no DELETE
this.value = mascaraData( this );
}
}
</script>
</head>
<body>
<form>
<input type="text" name="data" id="data" maxlength="10" />
</form>
</body>
</html> ainda falta impedir que o usuário digite letras e outras coisas que não são **[0-9]**William tua explicação foi boa, não quero de forma alguma descartar o uso de RegExp, é uma meta-linguagem muito poderosa, usei algumas vezes em shellscript :)
ocorre que não quero me prender na sintaxe no momento, como falei, meu foco é outro...
Portanto gostaria de terminar este script sem o uso dela, as correções:
De fato o evento onkeyup é falho para este propósito, corrigido para onkeypress.
Cara, entendi a lógica pra corrigir o problema no apagar os caracteres, porém não consegui entender como fazer isso...tenho que inibir a função quando pressionada as teclas ou da pra fazer um tratamento dentro da função?
você viu a minha implementação em #7 ?
http://forum.imasters.com.br/index.php?/topic/397592-mascara-data/page__view__findpost__p__1556742
uma forma simples que pensei, foi inibir a chamada da máscara no evento do botão BACKSPACE e DELETE
ou seja, esse trecho aqui de keyCode:
var kC = (document.all) ? event.keyCode : e.keyCode;
if( kC!=8 && kC!=46 )//não chamar a função nem no BACKSPACE e nem no DELETE
Estava tentendo entender o exemplo, hehe.
Seguinte, fiz conforme código abaixo porém está passando direto sempre, ou seja, não está entrando nos ifs pra colocar as '/'.
<script type="text/javascript">
function mascaraData(campoData)
{
var kC = (document.all) ? event.keyCode : e.keyCode;
var data = campoData.value;
if( kC!=8 && kC!=46 )
{
if(data.length == 2)
{
data += '/';
document.forms[0].data.value = data;
return true;
}
if(data.length == 5)
{
data += '/';
document.forms[0].data.value = data;
return true;
}
}
}
</script>
Esta linha:
var kC = (document.all) ? event.keyCode : e.keyCode;Captura o código ASCII do caractere digitado correto? Teria alguma fonte pra eu entender este evento?Abraço.
Após pesquisar um pouco percebi que o problema é incompatibilidade entre navegadores, alterei o evento para window.event.keyCode, funcionou no IE. No firefox usei o event.which mas não funciona, o que está errado? Depois que faze funcionar no FF faço a portabildiade nos dois navegadores...
var kC = event.which;
>
Esta linha:
var kC = (document.all) ? event.keyCode : e.keyCode;Captura o código ASCII do caractere digitado correto? Teria alguma fonte pra eu entender este evento?
Não.
esse keyCode, se refere ao código da tecla que foi pressionada.
o event no Firefox não é global, como no IE, portanto, você precisa passar ele como parâmetro:
function mascaraData( valor, e )entendeu ?
a parte var kC = ( teste lógico ) ? caso verdadeiro: caso falso;
é apenas um IF. O teste lógico que fiz, foi testar se o navegador implementa: document.all, se ele implementar isso, quer dizer que se trata do motor do Internet Explorer, e por isso, uso o event.keyCode(global, pode ser omitido o window., assim como não fazemos: window.document.getElementById.., mas apenas document.getEl... )
caso contrário, cai no 'else', que é o e que veio como parâmetro na função, e tem o valor do evento, que ocorreu.
para isso, sugiro passar assim no HTML:
<input type="text" name="data" onkeypress="mascaraData( this.value, event );" />
Bom, tente aperfeiçoar o teu script. O que sugeri, vejo como ideal, a minha segunda sugestão, é interessante também, pois não estou misturando javascript com html, e faço a atribuição da função totalmente com js, sem usar o atributo html do evento.. mas tá beleza.. vai estudando e fazendo..
tabelinha:
(desnecessária, já que você mesmo pode capturar o keyCode, mas talvez lhe ajude a entender oque ele é)
ps:não sei se foi o fórum, mas a identaçãop do teu código tá horrível.
Fica até dificil ler/entender o script.
Resolvi estudar as RegExp do teu exemplo, seguem as dúvidas quanto as mesmas.
Acho que é o fórum, pois meu código está todo indentado, estou usando o gedit pra escrever ele. :)
>
O segundo parâmetro da função: mascara(), é a máscara em ER a ser executada, no nosso caso:
function mdata(v){
v=v.replace(/\D/g,""); //Remove tudo o que não é dígito
v=v.replace(/(\d{2})(\d)/,"$1/$2");
v=v.replace(/(\d{2})(\d)/,"$1/$2");
v=v.replace(/(\d{2})(\d{2})$/,"$1$2");
return v;
}destrinchando cada linha, podemos ver que essa função recebe dígito por dígito, caracter por caracter que for sendo colocado no input text pelo usuário, pois invocamos todo o processo no evento onkeypress
Primeira linha:
v=v.replace(/\D/g,""); //Remove tudo o que não é dígito é bem simples.Funciona tudo com o replace() (função nativa da linguagem)
// é a sintaxe para se escrever uma ER, no qual, colocamos nossa expressão dentro dessas 2 barras, e caso precise de algum modificador, após a última
\D significa: não dígito, ou seja, qualquer coisa, que não seja 0,1,2,3,4,5,6,7,8,9
o g final, indica que é global, ou seja, sempre, não importa a posição, se entrar algo que não seja [0-9], o replace age, pois a ER bateu, e ai substitui por 'nada' ( "" )
As demais, linhas usam o conceito de grupo em ER, o primeiro grupo, vai parar no identificador $1, o segundo no $2 e assim por diante.
Um grupo é definido pelos parenteses.
Veja que é no segundo parâmetro da função replace() que colocamos as / , assim como as demais formatações das outras máscaras.
Pois é feito um replace em que
'Quando casar 2 digitos, mande eles pro primeiro grupo'
'Quando casar outros 2 digitos, mande eles pro segundo grupo'
'Agora faça o replace, colocando uma / no meio dos grupos'
A primeira linha, onde é removido tudo que é não-digito entendi.
Como funcionam os grupos de ER? O que seria esse identificador $1 e $2?
Eu entendi nessa parte que:
v=v.replace(/(\d{2})(\d)/,"$1/$2");
Vou entrar com 2 digitos, eles vão pro $1, vou entrar com mais um digito, ele vai pro $2..mas não é isso neh?
cara... ai ninguém melhor pra te explicar quem sabe explicar..
http://guia-er.sourceforge.net/
e esse livro aqui, que eu acho ótimo:
v=v.replace(/(\d{2})(\d)/,"$1/$2");
$1 e $2 são 'retrovisores'.. oque for 'casado' no primeiro grupo: (\d{2}), vai 'parar' no $1, e oque for casado pelo segundo grupo: (\d), irá para o $2 e assim por diante...
e oque eu adiciono entre os 2 grupos, é a barra:
"$1/$2"
pegou oque casou no primeiro grupo, colocou no $1
pegou oque casou no segundo grupo, colocou no $2
ai na hora do replace, faz: $1 / $2
mas e ai ? desistiu da mascarinha SEM ER ? ^_^
<html>
<head>
<title>Mascara data formulario</title>
<script type="text/javascript">
function mascaraData( campo, e )
{
var kC = (document.all) ? event.keyCode : e.keyCode;
var data = campo.value;
if( kC!=8 && kC!=46 )
{
if( data.length==2 )
{
campo.value = data += '/';
}
else if( data.length==5 )
{
campo.value = data += '/';
}
else
campo.value = data;
}
}
</script>
</head>
<body>
<form>
<input type="text" name="outra_data" id="outra_data" maxlength="10" onkeypress="mascaraData( this, event )" />
</form>
</body>
</html> mas é como eu disse, ainda sobra o problema de poder digitar 'não números' ^_^
dá uma olhada nessa máscara com ER:
http://forum.imasters.com.br/index.php?/topic/392121-identificar-somente-a-quantidade-de-caracteres-alfanumericos-digitados/page__view__findpost__p__1535363