CPF/CNPJ Input Mask

Add CPF/CNPJ mask in the same form field on Ionic 3. DEMO
Independent of which one is inputed either a CPF or a CNPJ. After a couple of days working for a solution I create myself this one simple that works. So I would like to share with the community that solution, and if you want you can improve it and share again.

login.html

<form #loginForm="ngForm">
  <ion-item>
    <ion-label floating>CPF/CNPJ</ion-label>
    <ion-input [(ngModel)]="cpf_cnpj" (blur)="cpf_cnpj = format(cpf_cnpj)" name="cpf_cnpj"></ion-input>
  </ion-item>
  <button ion-button full type="submit" color="sicor" (tap)="login(signForm.value)">Login</button>
</form>

login.ts


import { MenuController, NavParams, ModalController } from 'ionic-angular';
import { IonicPage, NavController } from 'ionic-angular';
import { AlertController } from 'ionic-angular';
import { Component } from '@angular/core';

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {

  cpf_cnpj = '';
  DECIMAL_SEPARATOR=".";
  GROUP_SEPARATOR=",";
  pureResult: any;
  maskedId: any;
  val: any;
  v: any;

constructor(
  public modalCtrl: ModalController, 
  private alertCtrl: AlertController,
  private menu: MenuController,
  public navCtrl: NavController, 
  ){} 

  ionViewDidEnter() {
    this.menu.swipeEnable(false);
  }
  ionViewWillLeave(){
    this.menu.swipeEnable(true);
  }

  format(valString) {
    if (!valString) {
        return '';
    }
    let val = valString.toString();
    const parts = this.unFormat(val).split(this.DECIMAL_SEPARATOR);
    this.pureResult = parts;
    if(parts[0].length <= 11){
      this.maskedId = this.cpf_mask(parts[0]);
      return this.maskedId;
    }else{
      this.maskedId = this.cnpj(parts[0]);
      return this.maskedId;
    }
};

unFormat(val) {
    if (!val) {
        return '';
    }
    val = val.replace(/\D/g, '');

    if (this.GROUP_SEPARATOR === ',') {
        return val.replace(/,/g, '');
    } else {
        return val.replace(/\./g, '');
    }
};

 cpf_mask(v) {
    v = v.replace(/\D/g, ''); //Remove tudo o que nĂŁo Ă© dĂ­gito
    v = v.replace(/(\d{3})(\d)/, '$1.$2'); //Coloca um ponto entre o terceiro e o quarto dĂ­gitos
    v = v.replace(/(\d{3})(\d)/, '$1.$2'); //Coloca um ponto entre o terceiro e o 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
    return v;
}

 cnpj(v) {
    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 segundo e o terceiro dĂ­gitos
    v = v.replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3'); //Coloca ponto entre o quinto e 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 bloco de quatro dĂ­gitos
    return v;
}

  public login(formData) { 
       ....you auth code here.
}

Here is… I hope it helps you!

8 Likes

Bom dia Tom! Após aplicar a máscara no meu input, funciona corretamente, mas caso eu utilize uma validação com ngIf o campo não é validado no meu formulário. Se eu retirar a máscara funciona corretamente. Sabe o que pode ser?

Valeu

Olá @lcrevilari,
Eu teria que ver o código antes, mas o princípio é de que vai depender o que pretende com o ngIf="" e onde está aplicando. Se tentar colocar um ngIf="" na tag <ion-input> não vai ter resultado pois entrará em conflito com as outras funções na mesma tag, tente incluir o seu ngIf="" na tag <ion-item>. Ou se for alguma condição relacionada à entrada de dados, use as funções no Javascrit.

I would have to see the code before, but the principle is that it will depend on what you want with ngIf = “” and where you are applying it. If you try to put a ngIf = “” in the <ion-input> tag it will not work because it will conflict with the other functions in the same tag, try adding your ngIf = “” to the <ion-item> tag. Or maybe, if it is a condition related to data entry, use it on the functions in javascrit.

A parte do input do CPF, por exemplo, está assim:

<ion-item>
     <ion-label stacked>CPF</ion-label>      
     <ion-input type="tel" name="cpf" pattern=".{10,11}[0-9]+$" maxlength="11" [(ngModel)]="user.cpf" #cpf="ngModel" (blur)="user.cpf = format(user.cpf)" required></ion-input>
</ion-item>      
<ion-item *ngIf="cpf.errors && (cpf.dirty || cpf.touched)" class="text-danger">
     CPF contém 11 números!
</ion-item>

E a função para máscara do CPF, no meu .ts, está igual ao seu exemplo.

A máscara funciona, porém o meu formulário não fica válido e retorna o erro “CPF contém 11 números!”.

Grande @lcrevilari,
Pelo que ví você modificou o código sugerido neste tutorial, isso indica também que não leu a sugestão na resposta anterior. O que você está tentando fazer é uma validação de entrada de dados, e talvez você não tenha entendido para o que serve esta máscara. Esta serve para a entrada de dados tanto de um CPF quanto de um CNPJ, independente de qual for inserido será aplicada a devida máscara correspondente. Por isso, você não deve validar pelo número de algarismos, pois as duas entradas (CPF e CNPJ) possuem diferentes tamanhos. Se não é o que esperava, procure um plugin apenas para CPF, tem vários exemplos pela web.
Contribuindo… para qualquer outro tipo de validação, busque um exemplo que valide o formulário através do ngModel. Segue aqui um tutorial sobre validação.

loguei sĂł pra dar like, muito bom

1 Like

Obrigado @jnap! :grinning::ok_hand:
Legal receber o seu feedback!

Fiz o mesmo! Mandou muito @TomCosta!

1 Like

Muito obrigado amigo, estava precisando de uma validação como essa! Estou começando no ionic agora mas desde já agradeço… E como uso o Git, e sou um bom desenvolevedor, claro que deixei uma mensagem no meu código como forma de agradecimento… Screenshot%20from%202018-12-24%2015-02-11

1 Like

Que legal @starlley fico feliz por poder contribuir. E quanto ao comentário no código, parabéns! Man que belo exemplo! Desejo sucesso na sua carreira! Grande abraço!

Updating the link to the working DEMO code. If you have tried and couldn’t find it. Take a look, right now it is okay, it was fixed.