DEV Community

Roger Rosset
Roger Rosset

Posted on

How create CPF Input Mask on Salesforce Aura Framework

Brazilians systems that are related to person accounts and customer information, always use CPF inputs, and this type of input has it's own definitions. One of them is about the pattern.

When it comes to provide custom masks within Salesforce Aura lightning inputs, everything goes into a dark zone. One often used workaround, is to use custom regex pattern attribute with patternMismatch message:

messageWhenPatternMismatch="CPF Inválido. Por favor utilize o padrão 000.000.000-00"
pattern="[0-9]{3}.[0-9]{3}.[0-9]{3}-[0-9]{2}"

It works, but in terms of UX we can say it is not one of the best solutions possible.
invalid-cpf-mask.png

When working with Salesforce, specially Aura and LWC, we are always being careful about limitations, and Shadow Dom, so there is no default way to implement input masks as would be possible using pure JavaScript for example.

The good news is that after a little and simple development using pure JavaScript with Aura peculiarities, you can implement a automatic CPF input mask into your lightning:input field.

First of all, you need to create the following attribute:
<aura:attribute name="cpfValue" type="String" default=""/>

After that, create your lightning:input field that will be used to store the CPF information. The type here will be default, because we need the special characters on this input, otherwise, we would set the type as number, but it's not the case.
<lightning:input aura:id="cpf" label="{!v.cpfLabel}" value="{!v.cpfValue}" onchange="{!c.handleCpfChange}" class="input sfdc_usernameinput sfdc" maxlength="14" required="true"/>

In my case, all the inputs uses a defined label that comes from the design file, but you don't have to worry about this. The attributes that are needed for this implementation to work, is:
-maxlength
-value
-aura:id
-onchange

Now, going to the js controller, we will have the following code:

    handleCpfChange: function (component, event){
        let inputCpf = event.getParam("value");
        component.set("v.cpfValue", inputCpf);
        let size = component.get("v.cpfValue").length;
        if(size === 3 || size === 7){
            component.set("v.cpfValue", inputCpf+'.');
        }
        if(size === 11){
            component.set("v.cpfValue", inputCpf+'-');
        }
    }
Enter fullscreen mode Exit fullscreen mode

What this code is doing, is running every time the value on the cpf field changes, by the onchange attributed that we've set before. Each time it runs, it will save the event value on the inputCpf variable, and set the attribute v.cpfValue with that variable value. Also, each time it will read for the length of the attribute, and when this length reaches 3 or 7, it will understand that it's time to put a dot, and when it reaches a size of 11, it will understand that it's time to put a slash.

So, there you have. A custom made and ready to go CPF input mask. You can also use this logic to develop your own custom masks, the reasoning will be the same.

Alt Text

I hope this be useful!

Roger Rosset

Top comments (0)