Mask for CPF and CNPJ in the same field

Asked

Viewed 115,219 times

58

Hello, I looked for this doubt in the questions, but I could not find it. Well, I would like to make a field have the Cpf and cnpj masks depending on the number of characters typed. Here it doesn’t work totally well, because with several tests I did here, this my code didn’t work that I need. I don’t know if I should just change, or if I need to make another.

Follows the code:

$("#cpfcnpj").keypress(function(){
    $("#cpfcnpj").unmask();
    var tamanho = $("#cpfcnpj").val().length;

    if(tamanho == 11){
        $("#cpfcnpj").mask("999.999.99-99");
    } else if(tamanho == 14){
        $("#cpfcnpj").mask("99.999.999/9999-99");
    }                   
});

Note: I’m using this plugin.

  • Follow the tutorial https://github.com/RobinHerbots/jquery.inputmask and Cdn https://cdnjs.com/libraries/jquery.inputmask see you around.

  • Diego you saw my answer ?

7 answers

51


Try to use the largest operator equal to or less equal, below is an example.

$("#cpfcnpj").keydown(function(){
    try {
        $("#cpfcnpj").unmask();
    } catch (e) {}

    var tamanho = $("#cpfcnpj").val().length;

    if(tamanho < 11){
        $("#cpfcnpj").mask("999.999.999-99");
    } else {
        $("#cpfcnpj").mask("99.999.999/9999-99");
    }

    // ajustando foco
    var elem = this;
    setTimeout(function(){
        // mudo a posição do seletor
        elem.selectionStart = elem.selectionEnd = 10000;
    }, 0);
    // reaplico o valor para mudar o foco
    var currentValue = $(this).val();
    $(this).val('');
    $(this).val(currentValue);
});

Example in Jsfiddler: https://jsfiddle.net/z5qmwn1d/

  • I couldn’t get it here Hiago :(

  • I’ll put the example in Jsfiddler

  • Ready edited the answer, found an error in the code but already put an example in Jsfiddler

  • 3

    Descenessário esse if no Else...

  • Thank you very much Hiago, it’s working perfectly here!

  • @Luishenrique I agree, when I edited I didn’t even notice.

  • @Hiagosouza I put in my project but it didn’t work, need to put reference to some javascript file?

  • @Mauricioferraz, you need to have jQuery in your project.

  • I managed using a plugin: http://answall.com/questions/122147/plugin-da-digitalbush-para-mascara-cnpj-e-cpf-no-mesmo-campo/122152#122152

  • 3

    Here he is returning a character when he passes the point :(

  • Weird Lucas, tried using the Jsfiddler example

  • 4

    I tested and does not work correctly, it comes back a house when typing, test the sequence 123456789 and you will see the error.

  • 2

    I tried to perform a test and has a bug

  • What bug @Denisrudneidesouza? Using the same library? The bug is reproduced in the example I left in Fiddler?

  • I tested by the fiddle, when placing the fourth digit it moves to the end, defacing the final result

  • 2

    @Denisrudneidesouza really, it may have been some browser update, before it worked normally. I edited the response with the fix of this bug.

  • There may be anomalies in the focusout event when using this solution, I implemented an improvement: https://answall.com/a/269671/744 @Denisrudneidesouza

  • By pressing the tab, the mask deforms the field.

  • 1

    @Hiagosouza the line } else if(tamanho >= 11) { it is unnecessary to exchange for } else {

  • @Augustovasques you’re right, thank you for the remark!

  • Very helpful my friend, thank you

  • It would be better to use the @Matheus Miranda response just below, as it is in accordance with the plugin documentation ;-)

Show 17 more comments

39

In his documentation already has an example that is: On-the-fly Mask change, he used example with ZIP CODE, just change to CPF.

See the code below, how the CPF and CNPF in the same field:

var options = {
    onKeyPress: function (cpf, ev, el, op) {
        var masks = ['000.000.000-000', '00.000.000/0000-00'];
        $('.cpfOuCnpj').mask((cpf.length > 14) ? masks[1] : masks[0], op);
    }
}

$('.cpfOuCnpj').length > 11 ? $('.cpfOuCnpj').mask('00.000.000/0000-00', options) : $('.cpfOuCnpj').mask('000.000.000-00#', options);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.10/jquery.mask.js"></script>

<input class="cpfOuCnpj" value="11111111111" type="text">

Documentation: https://igorescobar.github.io/jQuery-Mask-Plugin/

If you prefer in Jsfiddle: http://jsfiddle.net/znuph72f/375/

Follows the discussion: https://github.com/igorescobar/jQuery-Mask-Plugin/issues/53

  • 4

    This should be the correct answer, since the one marked above presents bugs with Backspace, when trying to delete what was typed.

  • 1

    Matheus Miranda, very good, I was in need of a solution like this, I entered here in the forum and I saw your solution and inform you that I am using her expensive. Very simple and small. Congratulations.

  • @Edegersil how good you liked and be happy :D

  • This should be the right solution. Clean and according to the documentation.

11

The proposed solution does not work very well because the written boolean condition may present anomalies in the 'focusout' event'.

I propose the following solution:

$(document).on('keydown', '[data-mask-for-cpf-cnpj]', function (e) {

    var digit = e.key.replace(/\D/g, '');

    var value = $(this).val().replace(/\D/g, '');

    var size = value.concat(digit).length;

    $(this).mask((size <= 11) ? '000.000.000-00' : '00.000.000/0000-00');
});

This solution is better in the following respects:

  1. Works the selector having the document as a scope, that is, if the element is inserted after the loading of the DOM remains functional.
  2. Removes the need to use the 'setTimeout' function to adjust the selector.
  3. Uses the attribute 'data-Mask-for-Cpf-cnpj' to create an unobtrusive Javascript, which leaves the code clean, ie your element would look very elegant:

    ex.: < input type="text" data-Mask-for-Cpf-cnpj />

  • 2

    Best possible solution! Thank you man.

  • 1

    amazing your solution... solved my problem and walked created some variations for phone etc...

5

Are you using that Plugin? if it is the Maskedinput of Digitalbush follows an example:

$(".hibridCpf").on('focusin',function(){
    var target = $(this);
    var val = target.val();
    target.unmask();
    val = val.split(".").join("");
    val = val.split("-").join("");
    val = val.split("/").join("");
    target.val(val);
});
$(".hibridCpf").on('focusout',function(){
    var target = $(this);
    var val = target.val();
    val = val.split(".").join("");
    val = val.split("-").join("");
    val = val.split("/").join("");
    if (val.length==11) {
        target.mask("999.999.999-99");
        target.val(val);
    } else {
        if (val.length==14) {
            target.mask("99.999.999/9999-99");
            target.val(val);
        } else {
            target.val('');
        }
    }
});

Test this example on jsfiddle.

This server solution also for zip code fields where the user can report a Brazilian or American zip code, using a similar logic...

PS: A mask plugin that I recommend and started using is the Mask Plugin created by the Brazilian @igorescobar (Github), he gathered the Mask Input and Mask Money in a single with more customization options, worth checking out!

There is also a simpler solution to your question from @rray in that question, but uses another plugin called Input Mask.

3

$('#cpfcnpj').mask('000.000.000-00', {
  onKeyPress : function(cpfcnpj, e, field, options) {
    const masks = ['000.000.000-000', '00.000.000/0000-00'];
    const mask = (cpfcnpj.length > 14) ? masks[1] : masks[0];
    $('#cpfcnpj').mask(mask, options);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" crossorigin="anonymous"></script>

<div>
  <label>Insira um CPF ou CNPJ: </label>
  <input name="cpfcnpj" id="cpfcnpj" />
</div>

3

This way it worked for me. No focusin you remove the mask, no focusout you apply the mask by removing the special characters.

$(document).ready(function(e) {
  $(".cpfCnpj").unmask();
  $(".cpfCnpj").focusout(function() {
    $(".cpfCnpj").unmask();
    var tamanho = $(".cpfCnpj").val().replace(/\D/g, '').length;
    if (tamanho == 11) {
      $(".cpfCnpj").mask("999.999.999-99");
    } else if (tamanho == 14) {
      $(".cpfCnpj").mask("99.999.999/9999-99");
    }
  });
  $(".cpfCnpj").focusin(function() {
    $(".cpfCnpj").unmask();
  });
});

2

I went through this problem too, where it was necessary to have a dynamic mask that could change shape to CPF or CNPJ. And since I’m only using Javascript I used a library that uses Vanilla Javascript to create masks.

imask js

Using the imask you can create a dynamic mask by passing an array to the property mask where it contains the definition of its masks. And as a rule of change simply set as many characters as one of the masks will contain in maxLenght, see an example:

var maskCpfOuCnpj = IMask(document.getElementById('cpfcnpj'), {
			mask:[
				{
					mask: '000.000.000-00',
					maxLength: 11
				},
				{
					mask: '00.000.000/0000-00'
				}
			]
		});
<script src="https://unpkg.com/imask"></script>
<input id="cpfcnpj" type="text" placeholder="digite o CPF ou CNPJ" name="cpfcnpj" required>

The maxLength of the CPF mask has been specified for 11 digits, of course there may be variations, but it would be easy to implement these variations to define the mask.

The idea of IMask is the processing of input simply comparing the state of before and afterward, being the changes of states obtained through the event keydown which provides the status of the values.

See a guide to learn more about imask js.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.