O referido componente tem como pai um TextInput, uma propriedade ActualText, através da qual será possível buscar o valor do campo digitado sem formatação de CPF ou CNPJ, como pode ser observado nas possibilidades apresentadas na tabela 1.
Exemplos | |
---|---|
Valor do campo com máscara de CPF | 999.999.999-99 |
Valor do campo sem máscara de CPF | 99999999999 |
Valor do campo com máscara de CNPJ | 99.999.999/9999-99 |
Valor do campo sem máscara de CNPJ | 99999999999999 |
O artigo Criação de componentes no adobe flash builder, publicado nesse portal, auxilia leitores iniciantes, por abordar passo a passo a criação de componentes.
Abaixo será detalhado o processo de criação do componente CPF/CNPJ. Lembrando que a definição do nome e caminho de localização do projeto do componente (ou pacote) fica a critério pessoal de você leitor.
Na figura 1 pode-se observar a definição do nome do projeto e sua localização:
- Project Name (Nome do Projeto): CpfCnpjInput;
- Folder (Localização do projeto): D:\WWW\CpfCnpjInput;
As demais opções devem respeitar as configurações padrão.
Um pacote que deverá conter as classes do componente deve ser criado, conforme exemplificado na figura 2.
- Name: br.com.input
Dentro da pasta “br.com.input” deve ser criada a nova classe, no caso “CpfCnpjInput”, onde define-se os campos ‘Name’ e ‘Superclass’, ilustrados na Figura 3.
- Name: CpfCnpjInput.
- SuperClass: spark.components.TextInput.
Os passos realizados foram necessários para criar a estrutura de pacotes no Flash e a classe principal. Agora vamos para codificação.
Explicando a codificação do componente
Dentro do método construtor da classe, devem ser inseridos os eventos do componente.
- O evento FlexEvent.CREATION_COMPLETE será disparado quando o componente for criado.
- O evento FocusEvent.FOCUS_OUT será disparado sempre quando o usuário sair do foco do componente.
- Já o evento KeyboardEvent.KEY_DOWN será disparado quando o usuário acionar alguma tecla no teclado.
- Pela variável ActualText será possível buscar o valor do componente CPF/CNPJ sem formatação.
A codificação dos eventos pode ser observada na listagem 1.
[Bindable] public var actualText : String = ''; // Txt Sem Formatacao
public function CpfCnpjInput()
{
super();
// events listener
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreateComplete);
this.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
Na listagem 2 apresenta o método Create Complete, pelo qual define-se que o componente irá receber apenas números e o máximo de caracteres que o componente pode aceitar, neste caso 18.
// on Create Complete
private function onCreateComplete(event: FlexEvent) : void
{
this.restrict="0-9"; // somente números
this.maxChars=18; // máximo chars 18
}
Pelo método do evento Focus Out, apresentado na listagem 3, apenas é chamada a função que valoriza a variável ActualText, referente ao texto digitado sem formatação.
// on Focus Out
private function onFocusOut(event: FocusEvent): void
{
this.getActualText();
}
Pelo evento Key Down é chamado o método que busca o texto digitado sem formatação e realiza as seguintes verificações:
- Se a tecla acionada for um BACKSPACE retorna para a máscara CPF;
- Se o texto atual sem formatação for menor ou igual a 11, é inserida a máscara de CPF no componente;
- Se o texto atual for maior que 11 é inserida a mascara de CNPJ no componente.
A listagem 4 apresenta a codificação do evento Key Down.
// on Key Down
private function onKeyDown(event: KeyboardEvent):void {
this.getActualText();
if ( event.keyCode == Keyboard.BACKSPACE )
{
Format.returnCPF( this );
}
else if ( this.actualText.length <= 11 )
{
Format.CPF( this );
}
else if ( this.actualText.length > 11 )
{
Format.CNPJ( this ); }
}
Na listagem 5, fazendo uso de expressões regulares, é removida a máscara do campo retornando a String sem formatação.
// Busca o texto atual sem mascara
private function getActualText():void {
var ponto : RegExp = /\./g;
var hifen : RegExp = /\-/g;
var barra : RegExp = /\//g;
var str : String = '';
str = this.text.replace(ponto, ""); // remove pontos
str = str.replace(hifen, ""); // remove hifen
str = str.replace(barra, ""); // remove barra
this.actualText = str;
}
A codificação completa da Classe CpfCnpjInput é apresentada na listagem 6.
package br.com.input
{
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import mx.events.FlexEvent;
import spark.components.TextInput;
public class CpfCnpjInput extends TextInput
{
[Bindable] public var actualText : String = ''; // Txt sem formatacao
public function CpfCnpjInput()
{
super();
// events listener
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreateComplete);
this.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
// on Create Complete
private function onCreateComplete(event: FlexEvent) : void
{
this.restrict="0-9"; // somente nros
this.maxChars=18; // maximo chars 18
}
// on Focus Out
private function onFocusOut(event: FocusEvent): void
{
this.getActualText();
}
// on Key Down
private function onKeyDown(event: KeyboardEvent):void {
this.getActualText();
if ( event.keyCode == Keyboard.BACKSPACE )
{
Format.returnCPF( this );
}
else if ( this.actualText.length <= 11 )
{
Format.CPF( this );
}
else if ( this.actualText.length > 11 )
{
Format.CNPJ( this );
}
}
// busca o texto atual sem mascara
private function getActualText():void {
var ponto : RegExp = /\./g;
var hifen : RegExp = /\-/g;
var barra : RegExp = /\//g;
var str : String = '';
str = this.text.replace(ponto, ""); // remove pontos
str = str.replace(hifen, ""); // remove hifen
str = str.replace(barra, ""); // remove barra
this.actualText = str;
}
}
}
Prosseguindo com a criação do componente, deve ser declaradas as variáveis da classe Format que será responsável pela formatação da máscara, como pode ser observado na listagem 7.
// var genericas
private static var ponto : RegExp = /\./g;
private static var hifen : RegExp = /\-/g;
private static var barra : RegExp = /\//g;
// var cpf
private static var dig3 : RegExp = /^\d{3}$/;
private static var dig9 : RegExp = /^\d{3}.\d{3}.\d{3}$/;
// var cnpj
private static var cnpj : RegExp = /^\d{2}.\d{3}.\d{3}\/\d{4}-\d{2}$/;
// var return cpf
public static var returnMaskCPF : RegExp = /^\d{2}.\d{3}.\d{3}\/\d{3}$/;
Após a codificação das variáveis, deve-se implementar o primeiro método responsável pela formatação da máscara de CPF, com as seguintes características:
- Se a quantidade de caracteres digitados pelo usuário for menor que 3, apenas retorna para o método que chamou, não sendo necessário colocar a máscara.
- Verifica se o tamanho do texto é maior ou igual a 3 e menor que 9.
- Em seguida localiza o último ponto se existir, copia 3 posições e realiza um teste utilizando expressão regular, se o tamanho da string copiada for de 3 caracteres então insere um ponto no final da string (está parte do código é responsável por inserir a máscara no formato ###.###.###).
- Outra verificação que deve ser realizada é se o tamanho do texto é igual a 9 caracteres, quando essa condição for verdadeira, deve ser inserido o traço.
Na listagem 8 é apresentado o método responsável pela formatação da mascara de CPF.
public static function CPF(txt:CpfCnpjInput):void {
// não é necessário colocar a mascara!
if ( txt.text.length < 3 )
{
return;
}
if ( txt.text.length >= 3 && txt.text.length < 9 )
{
// encontra o último ponto se existir
var ponto : int = txt.text.lastIndexOf(".", txt.text.length);
var start : int = ponto + 1;
var tam : int = 3;
// copia apenas 3 dígitos
var substr : String = txt.text.substr(start, tam);
if ( dig3.test(substr) )
{
// insere o ponto
txt.text += ".";
}
}
else
{
if ( dig9.test(txt.text) )
{
// insere o traço
txt.text += "-";
}
}
posicionaCursorFinal(txt);
}
A listagem 9 apresenta o método pela formatação da máscara de CNPJ. Basicamente neste método é removida a máscara atual do componente, criando à máscara e retornando o CNPJ formatado.
public static function CNPJ(txt:CpfCnpjInput):void {
var str : String = "";
str = txt.text.replace(ponto, ""); // remove pontos
str = str.replace(hifen, ""); // remove hifen
var doisDigitosPonto : String = str.substr(0, 2); // copia 2 digitos
var tresDigitosPonto : String = str.substr(2, 3); // copia 3 digitos
var tresDigitosBarra : String = str.substr(5, 3); // copia 3 digitos
var quatDigitosTraco : String = str.substr(8, 4); // copia 4 digitos
var doisDigitosFim : String = str.substr(12, 2); // copia 2 digitos
// novo cnpj
var newCNPJ : String =
doisDigitosPonto + "." +
tresDigitosPonto + "." +
tresDigitosBarra + "/" +
quatDigitosTraco + "-" +
doisDigitosFim;
if ( cnpj.test(newCNPJ) )
{
txt.text = newCNPJ;
}
posicionaCursorFinal(txt);
}
Na listagem 10 é realizado o retorno da máscara do CPF. Neste método verifica se o texto digitado pelo usuário possui a quantidade de caracteres para inserir a máscara de CPF novamente.
// ** Exemplo.: 01.622.347/996
public static function returnCPF(txt:CpfCnpjInput):void {
if ( returnMaskCPF.test(txt.text) )
{
var str : String = "";
str = txt.text.replace(ponto, ""); // remove pontos
str = str.replace(barra, ""); // remove barra
var tresDigitosPonto0 : String = str.substr(0, 3); // copia 3 digitos
var tresDigitosPonto3 : String = str.substr(3, 3); // copia 3 digitos
var tresDigitosTraco6 : String = str.substr(6, 3); // copia 3 digitos
var doisDigitosTraco9 : String = str.substr(9, 2); // copia 2 digitos
// novo cnpj
var newCPF : String =
tresDigitosPonto0 + "." +
tresDigitosPonto3 + "." +
tresDigitosTraco6 + "-" +
doisDigitosTraco9;
txt.text = newCPF;
}
posicionaCursorFinal(txt);
}
O método que posiciona o cursor no final do campo pode ser observado na listagem 11.
// posiciona o cursor no final
private static function posicionaCursorFinal(txt:CpfCnpjInput):void {
txt.selectRange(txt.text.length+1, txt.text.length+1);
}
A listagem 12 apresenta a codificação completa da classe Format.
package br.com.input
{
import mx.controls.TextInput;
// classe Static Para Formatar as Mask
public class Format
{
// var genericas
private static var ponto : RegExp = /\./g;
private static var hifen : RegExp = /\-/g;
private static var barra : RegExp = /\//g;
// var cpf
private static var dig3 : RegExp = /^\d{3}$/;
private static var dig9 : RegExp = /^\d{3}.\d{3}.\d{3}$/;
// var cnpj
private static var cnpj : RegExp = /^\d{2}.\d{3}.\d{3}\/\d{4}-\d{2}$/;
// var return cpf
public static var returnMaskCPF : RegExp = /^\d{2}.\d{3}.\d{3}\/\d{3}$/;
// ******************************************* //
// ** Format Mask CPF ** //
// ******************************************* //
public static function CPF(txt:CpfCnpjInput):void {
// não é necessario colocar a mascara!
if ( txt.text.length < 3 )
{
return;
}
if ( txt.text.length >= 3 && txt.text.length < 9 )
{
// acha o último ponto se existir
var ponto : int = txt.text.lastIndexOf(".", txt.text.length);
var start : int = ponto + 1;
var tam : int = 3;
// copia apenas 3 digitos
var substr : String = txt.text.substr(start, tam);
if ( dig3.test(substr) )
{
// insere o ponto
txt.text += ".";
}
}
else
{
if ( dig9.test(txt.text) )
{
// insere o traco
txt.text += "-";
}
}
posicionaCursorFinal(txt);
}
// ******************************************* //
// ** Format Mask CNPJ ** //
// ******************************************* //
public static function CNPJ(txt:CpfCnpjInput):void {
var str : String = "";
str = txt.text.replace(ponto, ""); // remove pontos
str = str.replace(hifen, ""); // remove hifen
var doisDigitosPonto : String = str.substr(0, 2); // copia 2 digitos
var tresDigitosPonto : String = str.substr(2, 3); // copia 3 digitos
var tresDigitosBarra : String = str.substr(5, 3); // copia 3 digitos
var quatDigitosTraco : String = str.substr(8, 4); // copia 4 digitos
var doisDigitosFim : String = str.substr(12, 2); // copia 2 digitos
// novo cnpj
var newCNPJ : String =
doisDigitosPonto + "." +
tresDigitosPonto + "." +
tresDigitosBarra + "/" +
quatDigitosTraco + "-" +
doisDigitosFim;
if ( cnpj.test(newCNPJ) )
{
txt.text = newCNPJ;
}
posicionaCursorFinal(txt);
}
// ******************************************* //
// ** Return Mask CPF ** //
// ******************************************* //
// ** Exemplo.: 01.622.347/996
public static function returnCPF(txt:CpfCnpjInput):void {
if ( returnMaskCPF.test(txt.text) )
{
var str : String = "";
str = txt.text.replace(ponto, ""); // remove pontos
str = str.replace(barra, ""); // remove barra
var tresDigitosPonto0 : String = str.substr(0, 3); // copia 3 digitos
var tresDigitosPonto3 : String = str.substr(3, 3); // copia 3 digitos
var tresDigitosTraco6 : String = str.substr(6, 3); // copia 3 digitos
var doisDigitosTraco9 : String = str.substr(9, 2); // copia 2 digitos
// novo cnpj
var newCPF : String =
tresDigitosPonto0 + "." +
tresDigitosPonto3 + "." +
tresDigitosTraco6 + "-" +
doisDigitosTraco9;
txt.text = newCPF;
}
posicionaCursorFinal(txt);
}
// posiciona o cursor no final
private static function posicionaCursorFinal(txt:CpfCnpjInput):void {
txt.selectRange(txt.text.length+1, txt.text.length+1);
}
}
}
Neste artigo foi apresentada de forma prática e didática a criação de um componente CPF/CNPJ, a fim de que leitores possam utilizar em suas aplicações.
Bom pessoal por hoje é isso, espero que tenham gostando da Criação deste Componente e possam utilizar ele em suas aplicações.
Clique aqui se quiser baixar o projeto do componente, com os códigos fontes.