Ionic 3+ CPF/CNPJ input mask

Published Nov 12, 2017
Ionic 3+ CPF/CNPJ input mask

About me

As the most of us, I am a mobile developer that always is facing challenges and looking for solutions. Some times it can be solved by using plugins, some times isn't.

The problem I wanted to solve

It was needed to create an input mask to CPF/CNPJ in a login/register form on a mobile app developed using Ionic Framework.
Maybe it seems like a simple task, or maybe it could be solved using a plugin, but it couldn't. After looking for a solution I discovered that some plugins don't build in a --prod --release cli commands. So, without alternatives I had to build my own input mask to a form.

What is # Ionic 3 CPF/CNPJ input mask?

So, what are we talking about?

  • CPF
  • CNPJ

Well, CPF is the citizenship ID and CNPJ is the company ID in Brazil. So it is used some times to recognize you in a system, or just used to do a login in a app. The problem is, the first one have eleven digits and the second has fourteen digits and the input mask have to adapt itself to it independent of which one is typed as input.

Tech stack

I created some javascript functions that made the hard work to check the input and insert the mask according to the length of the typed data. So you can see it in the example code:

The process of building # Ionic 3 CPF/CNPJ input mask

In the .html file:

<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>

In the .ts file:

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 all that is not digits
    v = v.replace(/(\d{3})(\d)/, '$1.$2'); //Insert a dot between the third and quarter digit
    v = v.replace(/(\d{3})(\d)/, '$1.$2'); //Insert a dot between the third and quarter digit again
    v = v.replace(/(\d{3})(\d{1,2})$/, '$1-$2'); //Insert an dash between the third and quarter digit
    return v;
}

 cnpj(v) {
    v = v.replace(/\D/g, ''); //Remove all that is not digits
    v = v.replace(/^(\d{2})(\d)/, '$1.$2'); //Insert a dot between the second and third digits
    v = v.replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3'); //Insert a dot between the fifth and sixth digits
    v = v.replace(/\.(\d{3})(\d)/, '.$1/$2'); //Insert a slash between the eighth and ninth digits
    v = v.replace(/(\d{4})(\d)/, '$1-$2'); //Insert an dash after the quarter digit
    return v;
}

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

Challenges I faced

The challenge was to solve my problem in a short time because the dead line to finish the app was almost ending, and till this moment I didn't have find any solution done to solve it.

Key learnings

The keys learning are research, try, understand and try to solve.

Tips and advice

First I would like to suggest you to try to develop the solution yourself before install any plugins in your project that can put you in bad situations.

Final thoughts and next steps

I hope it can help in some way. I will be increasing the quality of my code and knowledge and sharing it in the community as well. If you have doubts, please ask me. Have a nice time, see you soon!

Here you can find the code used to make this solution:

Discover and read more posts from Everton Costa
get started
Enjoy this post?

Leave a like and comment for Everton