máscara em campos de formulário

Uma solução simples e crossbrowser com expressões regulares

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. Mas antes, deixe-me tentar dissuadí-lo da idéia.

Porque você não deveria usar máscaras de digitação em campos de formulário na web

Quando você desenvolve um programa para Desktop, você tem um relativo controle sobre como esse programa vai aparecer na tela de seus usuários. Na web a grande variedade de dispositivos, sistemas operacionais e navegadores torna isso muito complicado. Nós projetamos um site ou sistema na web não pensando em oferecer a mesma experiência para todos os usuários, mas a melhor experiência que cada usuário pode ter em sua plataforma. Isso deve incluir, por exemplo, usuários de dispositivos móveis.

Um segundo motivo é a complexidade dessas máscaras. Quando você cria um campo com máscara no Visual Basic, Delphi ou .NET, por exemplo, esse campo será tratado com um código complexo, que levou muito tempo para ser desenvolvido e foi testado à exaustão. A Microsoft e a Borland já fizeram este trabalho para você, e este código complexo está compilado numa DLL que já está no sistema operacional do usuário ou será instalada com seu sistema, e não será feito o download do código cada vez que o usuário acessar a tela, como acontece na web. Ao desenvolver, você mesmo, uma máscara de validação dessas, você vai consumir um bocado de tempo, se envolver numa complexidade nada empolgante, para ter um resultado que pode atrapalhar seus usuários ao invés de ajudá-los. Escolha um site qualquer que implementa esse tipo de máscara e tente, por exemplo, digitar no meio do campo e não no final. Ou seja, digite um pouco no campo, clique no meio do campo ou coloque o cursor no meio usando as setas do teclado e digite mais um pouco. Se você encontrar uma máscara que funcione bem assim em qualquer navegador, o que é muito raro, exiba o código fonte e você vai entender o que eu chamo de complexidade.

Se você puder evitar o uso de máscaras em campos de formulário, evite. Há alternativas estupidamente simples para isso. Por exemplo, instruir o usuário a respeito de como digitar no campo, e validar apenas no submit:

Se você realmente precisa que o usuário tenha um "auxílio" na digitação, que ele saiba onde começa e termina cada parte do campo, pode fazer algo assim:

Isso vai funcionar tão bem no Lynx e no Opera Mini quanto nos navegadores para Desktop.

Ok, sua conversa é boa, mas eu realmente preciso de uma máscara de digitação

Tudo bem, eu entendo, às vezes o sistema que você está desenvolvendo realmente precisa deste tipo de coisa. E às vezes não, mas você simplesmente não consegue convencer seu chefe ou o cliente disso. Então deixe-me mostrar uma maneira simples de desenvolver esse tipo de máscara, contornando a complicada captura de teclas do navegador. Para começar, vamos criar as funções que disparam a validação:

function mascara(o,f){
    v_obj=o
    v_fun=f
    setTimeout("execmascara()",1)
}

function execmascara(){
    v_obj.value=v_fun(v_obj.value)
}

A função máscara recebe um objeto o e uma função f, e os guarda nas variáveis globais v_obj e v_fun. Ela chama então num Timeout a função execmascara, que executa a função v_fun no valor do objeto v_obj. A função v_fun pode fazer qualquer coisa que você quiser que receba uma string e retorne outra. Por exemplo, para fazer um campo que converte o texto para leech script, usamos:

function leech(v){
    v=v.replace(/o/gi,"0")
    v=v.replace(/i/gi,"1")
    v=v.replace(/z/gi,"2")
    v=v.replace(/e/gi,"3")
    v=v.replace(/a/gi,"4")
    v=v.replace(/s/gi,"5")
    v=v.replace(/t/gi,"7")
    return v
}

E no formulário:

<input id="ileech" onkeypress="mascara(this,leech)" />

Veja funcionando:

Talvez você esteja se perguntando porque a função máscara chama a execmascara num Timeout, ao invés de simplesmente executar a função f sobre o valor do objeto. Acontece que a função de validação é chamada antes de o navegador alterar o valor de um objeto. Ao pressionar uma tecla, o navegador executa primeiro a função de validação e, em seguida, se ela não cancelar o evento, altera o valor do campo. Isso nos obriga a testar o evento, capturando a tecla pressionada, o que é origem de muita dor de cabeça em navegadores diferentes. O uso do Timeout faz com que, quando a execmascara for chamada, o valor do campo de formulário já tenha sido alterado pelo navegador, uma vez que a função máscara não cancela o evento.

Criando funções de validação com expressões regulares

O uso desse método nos permite tratar o campo de formulário com um tratamento de string, o que é muito mais fácil de fazer do que tratar a captura de tecla. O poder e a flexibilidade das expressões regulares será muito útil agora. Por exemplo, para validar a digitação num campo para que contenha apenas números, podemos usar:

function soNumeros(v){
    return v.replace(/\D/g,"")
}

Veja como fica:

Há um inconveniente: o fato de o que você digita aparecer por uma fração de segundo. Mas a simplicidade no código e a liberdade de poder usar expressões regulares compensa bastante. Em alguns minutos escrevi as máscaras a seguir:

Você pode ver o javascript exibindo o fonte dessa página. Divirta-se.


Sobre o Autor

Elcio Ferreira mantém o blog de tecnologia fechaTag, é um dos mantenedores do site sobre padrões web Tableless.com.br e é diretor da Visie Padrões Web, onde ensina Javascript e Ajax.

Este artigo foi escrito em resposta a uma dúvida de um aluno dos cursos da Visie.


Comentários Aqui