Validar CPF, CNPJ e colocar mascara ao detectar quantidade

Olá pessoal,

Quero saber se alguem já fez isso, de validar o CPF ou CNPJ digitado e alem disso aplicar uma mascara a depender da quantidade de numeros, ou seja, para cpf são 11 e para cnpj são mais ou menos 14 números.

Agradeço desde já;

Bom, para acrescentar a máscara ao seu campo é fácil, podes utilizar o CMaskedTextField que já vem no Yii, ou alguma outra extensão. Eu particularmente gosto muito da extensão MeioMask.

Em ambos os links você vai encontrar exemplos de utilização. Se precisares, posso postar algum exemplo meu aqui…

Quanto a questão de validar CPF e/ou CNPJ, tens de adicionar os validadores destes dados ao teu projeto.

Para isso, baixe os validadores:

  • CPFValidator

  • CNPJValidator

Após finalizar o download, adicione os validadores a pasta validators dentro da pasta extensions (se a pasta não existir, crie).

Depois é só adicionar ao seu modelo as novas regras…


public function rules()

{

    return array(

	// [...]

	

	array('cpf', 'ext.validators.CPFValidatorName'),

	array('cnpj', 'ext.validators.CNPJValidatorName'),

	

	// [...]

    );

}

Obrigado amigo. Mas no caso dele identificar automaticamente quando digito no campo, você sabe? Tipo tenho uma input text "CPF/CNPJ", ai quando o usuário digitar ele validar se é um ou outro e já colocar a mascara?

Humm, acho que entendi, você quer ter um campo que aceite tanto CPF, quanto CNPJ e só validar e colocar a máscara após o usuário digitar, correto?

Se for isso, não cheguei a ver nada ainda que resolva o seu caso, mas tudo é possível, se estivesse com um pouco de tempo livre tentaria ver algo aqui, mas fica a sugestão de utilizar o evento OnChange e alguns dos métodos dos modelos, como o beforeValidate por exemplo, para resolver o problema.

camarada,

tirando a parte da máscara de campo, a validação no model pode ficar assim:


public function rules()

{

		return array(

				array('cpf_cnpj','validaCPF_CNPJ'),

		);

}


public function validaCPF_CNPJ($attribute, $params)

{

		//código de validação

		

		//if cpf inválido

		$this->addError($attribute, 'CPF inválido!);

		

		//else cnpj inválido

		$this->addError($attribute, 'CNPJ inválido!);

}

vc pode diferenciar se é cpf ou cnpj pelo tamanho do conteúdo do campo e fazer a validação necessária.

Acácio,

Uma solução que sempre faço para não ter uma javascript grande.

Faça dois campos textField, mais deixa eles escondido, adicionando uma class com display:none.

Agora antes desses textField’s, você adiciona 2 radio, para selecionar se é Pessoa Física ou Jurídica, ai você mostra o campo conforme a seleção do cliente.

Assim você evita de usar 1 campo para 2 valores, podendo assim limitar o máximo de caracteres para cada campo.

Meu modelo:




Yii::app()->clientScript->registerScript('jquery', "


$('select[id=Cliente_tipopessoa]').live('change', function(){

    var value = $(this).val();


    if(value == 'f'){

        $('div[class=cpf]').show();

        $('div[class=cnpj]').hide();

        $('input[id=Cliente_cnpj]').val('');

    } else if(value == 'j'){

        $('div[class=cnpj]').show();

        $('div[class=cpf]').hide();

        $('input[id=Cliente_cpf]').val('');

    }

});


");


<div>

        <?php echo $form->labelEx($model, 'tipopessoa'); ?>

        <?php

        $tipopessoa = array(

            'f' => 'Pessoa Física',

            'j' => 'Pessoa Jurídica'

        );

        echo $form->dropDownList($model, 'tipopessoa', $tipopessoa, array('prompt' => 'Selecione'));

        ?>

        <?php echo $form->error($model, 'tipopessoa'); ?>

    </div>

<div class="cpf">

        <?php echo $form->labelEx($model, 'cpf'); ?>

        <?php echo $form->textField($model, 'cpf', array('maxlength' => 14)); ?>

        <?php echo $form->error($model, 'cpf'); ?>

    </div>

<div class="cnpj">

        <?php echo $form->labelEx($model, 'cnpj'); ?>

        <?php echo $form->textField($model, 'cnpj', array('maxlength' => 18)); ?>

        <?php echo $form->error($model, 'cnpj'); ?>

    </div>




Newerton,

Apliquei isso e deu certinho. Apenas um detalhe…fazendo desta forma tive que tirar o cpf e o cnpj da rule required, bem como da validação pois os dois nunca serão digitados no mesmo form. Tem alguma maneira de manter estas regras no model ou é do modo como fiz mesmo?

Ricardo,

Eu valido isso no beforeValidate() no seu model, coloca uma condição mais ou menos assim:


if($this->tipopessoa == 'f')

    $this->cnpj = 0;

else

    $this->cpf = 0;

Assim os campos recebe algum valor.

Ou senão você pode remover eles do required, e mesmo assim usar condição no beforeValidate()


if($this->tipopessoa == 'f'){

    if(empty($this->cpf)){

        $this->addError('cpf', 'CPF não pode ser vazio.')

    }

} else if($this->tipopessoa == 'j'){

    if(empty($this->cnpj)){

        $this->addError('cnpj', 'CNPJ não pode ser vazio.')

    }

}

Entendi Newerton, mais uma vez muito obrigado!! Vou tentar aqui e qualquer coisa te falo. Valeu!!!

Vou precisar fazer isso em breve, valeu pela suggestão Newerton.

Galera, tudo bem? Tenho uma dúvida quanto a validação de CPF e CNPJ. Tenho um form que cadastra cliente fisico ou juridico, ele mostra um ou outro com uma funcao javascript. Quando vou cadastrar ele pede validação dos 2 campos. Tirei a validação e na hora de salvar ele tá salvando os 2 campos, e o que não foi preenchido fica todo zerado.

Por exemplo CPF 000000000-00 CNPJ 02.584.520/0854-90. Alguem pode me ajudar?

Meu _form.php

<script>

	function muFun(obj){


		if(obj==&quot;CPF&quot;){


		document.getElementById('CPF').style.display=&quot;block&quot;; 


		document.getElementById('CNPJ').style.display=&quot;none&quot;; 


		return false;


		}else{


		document.getElementById('CNPJ').style.display=&quot;block&quot;; 


		document.getElementById('CPF').style.display=&quot;none&quot;; 


		return false;


		}


	}


&lt;/script&gt;








&lt;p class=&quot;note&quot;&gt;Campos com &lt;span class=&quot;required&quot;&gt;*&lt;/span&gt; são obrigatórios.&lt;/p&gt;





&lt;?php echo &#036;form-&gt;errorSummary(&#036;model); ?&gt;





&lt;div class=&quot;row&quot;&gt;


    &lt;?php echo &#036;form-&gt;labelEx(&#036;model, 'Tipo de Cliente: &amp;nbsp;*&amp;nbsp;'); ?&gt;


    &lt;?php echo &#036;form-&gt;dropDownList(&#036;model, 'tipocliente', array(''=&gt;'Selecione','CPF'=&gt;'Cliente Físico','CNPJ'=&gt;'Cliente Jurídico'),array('onchange'=&gt;'return muFun(this.value)')); ?&gt;


    &lt;?php echo &#036;form-&gt;error(&#036;model, 'tipocliente'); ?&gt;


&lt;/div&gt;





&lt;div id=&quot;CPF&quot; style=&quot;display:none&quot;&gt;


	&lt;div class=&quot;row&quot; id=&quot;CPF&quot;&gt;


		&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'C P F: &amp;nbsp;*&amp;nbsp;'); ?&gt;


		&lt;?php


			&#036;this-&gt;widget('CMaskedTextField', array(


			'model' =&gt; &#036;model,


			'attribute' =&gt; 'cpf',


			'mask' =&gt; '999.999.999-99',


			'htmlOptions' =&gt; array('size' =&gt; 14)


			))


		?&gt;


		&lt;?php echo &#036;form-&gt;error(&#036;model,'cpf'); ?&gt;


	&lt;/div&gt;


&lt;/div&gt;





&lt;div id=&quot;CNPJ&quot; style=&quot;display:none&quot;&gt; 


	&lt;div class=&quot;row&quot; id=&quot;CNPJ&quot;&gt;


		&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'C N P J &amp;nbsp;*&amp;nbsp;'); ?&gt;


	&lt;?php


		&#036;this-&gt;widget('CMaskedTextField', array(


		'model' =&gt; &#036;model,


		'attribute' =&gt; 'cnpj',


		'mask' =&gt; '99.999.999/9999-99',


		'htmlOptions' =&gt; array('size' =&gt; 14)


		))


	?&gt;


	&lt;?php echo &#036;form-&gt;error(&#036;model,'cnpj'); ?&gt;


	&lt;/div&gt;


&lt;/div&gt;





&lt;div class=&quot;row&quot;&gt;


	&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'Nome / Razão Social: *&amp;nbsp;'); ?&gt;


	&lt;?php echo &#036;form-&gt;textField(&#036;model,'nome',array('size'=&gt;60,'maxlength'=&gt;200)); ?&gt;


	&lt;?php echo &#036;form-&gt;error(&#036;model,'nome'); ?&gt;


&lt;/div&gt;

Newerton estou tentando aplicar este seu modelo em meu projeto da faculdade, porem estou utilizando o Yii2, como ficaria neste caso? pode me auxiliar em como chamar a função js para a mesma cituação.

Muito obrigado.

Lucas,

Você quer saber sobre a mascara dos documentos ou usar os tipo de pessoa?

Então Newerton na verdade eu preciso saber como usar os tipos de pessoa, preciso que ao selecionar Pessoa fisica exiba os campos CPF e RG, e ao selecionar Pessoa Juridica exiba os Campos CNPJ e Inscrição Estadual.

Obrigado.

Lucas,

Posta aqui o seu _form, quero ver os nomes dos campos, para te mostrar como será o js.

Segue abaixo o arquivo _form:

Muito obrigado.




<div class="form">

    <div class="col-md-10">

    <div class="well">


    <?php $form = ActiveForm::begin([

    

    ]); ?>

    <?//= $form->errorSummary($pessoa); ?>




    <?= $form->field($pessoa, 'tipopessoa')->radioList(array('1' => 'Pessoa Física', 

                                                             '2' => 'Pessoa Jurídica')); ?>

    

    <div class="row">

        <div class="cpf">

            <div class="col-md-3">

                <?= $form->field($pessoa_fisica, 'cpf')->textInput() ?><br>

            </div>

        </div>

        <div class="rg">

            <div class="col-md-3">

                <?= $form->field($pessoa_fisica, 'rg')->textInput() ?><br>

            </div>

        </div>

        <div class="cnpj">

            <div class="col-md-3">

                <?//= $form->field($pessoa_juridica, 'cnpj')->textInput() ?><br>

            </div>

        </div>

        <div class="inscricaoestadual">

            <div class="col-md-3">

                <?//s= $form->field($pessoa_juridica, 'inscricaoestadual')->textInput() ?><br>

            </div>

        </div>

    </div>

    <div class="row">

        <div class="nome">

            <div class="col-md-6">

                <?= $form->field($pessoa, 'nome')->textInput(['maxlength' => true]) ?>

            </div>

        </div>

        <div class="sexo">

            <div class="col-md-1">

                <?= $form->field($pessoa_fisica, 'sexo')->textInput(['maxlength' => true]) ?>

            </div>

        </div>

        <div class="datanascimento">

            <div class="col-md-2">

                <?= $form->field($pessoa_fisica, 'datanascimento')->textInput(['maxlength' => true]) ?>

            </div>

        </div>

    </div>


    <hr>


    <div class="row">

        <div class="telefoneTipo">

            <div class="col-md-2">

                <?= $form->field($telefone, 'tipo')->dropDownList(['Fixo' => 'Fixo',

                                                                  'Celular' => 'Celular',

                                                                  'Auxiliar' => 'Auxiliar']) ?>

            </div>

        </div>

        <div class="ddd">

            <div class="col-md-1">

                <?= $form->field($telefone, 'ddd')->textInput() ?>

            </div>

        </div>

        <div class="telefoneNumero">

            <div class="col-md-2">

                <?= $form->field($telefone, 'numero')->textInput() ?>

            </div>

        </div>

    </div>


    <hr>


    <div class="row">

        <div class="col-md-6">

            <?= $form->field($pessoa, 'logradouro')->textInput(['maxlength' => true]) ?>

        </div>

        <div class="col-md-2">

            <?= $form->field($pessoa, 'numero')->textInput() ?>

        </div>

        <div class="col-md-3">

            <?= $form->field($pessoa, 'cep')->textInput(['maxlength' => true]) ?>

        </div>

        

    </div>


    <div class="row">

        <div class="col-md-2">

            <?= $form->field($pessoa, 'uf')->dropDownList($uf); ?>

        </div>

        <div class="col-md-3">

            <?= $form->field($pessoa, 'cidade')->textInput(['maxlength' => true]) ?>

        </div>

        <div class="col-md-3">

            <?= $form->field($pessoa, 'bairro')->textInput(['maxlength' => true]) ?>

        </div>

        <div class="col-md-3">

            <?= $form->field($pessoa, 'complemento')->textInput(['maxlength' => true]) ?>

        </div>

    </div>


    <div class="row">

        <div class="col-md-4">

            <?= $form->field($pessoa, 'email')->textInput(['maxlength' => true]) ?>

        </div>

    </div>


    </div>


    <div class="form-group">

        <?=Html::submitButton($pessoa->isNewRecord ? 'Salvar' : 'Update', ['class' => $pessoa->isNewRecord ? 'btn btn-success' : 'btn btn-primary'])?>

    </div>

</div>

</div>




    <?php ActiveForm::end(); ?>




</div>



Pessoal, resolvi aproveitar o tópico pois meu objetivo é validar um campo de RG.

Estou iniciando na programação (fazendo estágio, apesar de já estudar em casa há uns 2 anos) e o sistema da empresa usa o Yii. Estou me batendo por estar aprendendo o MVC na prática, junto com o framework. Mas a empresa optou por este caminho e preciso obedecer.

O que preciso é simples (creio eu): validar que o campo RG receba apenas números e com a máscara 9.999.999-9. Até fiz um script seguindo o link sobre máscara com jquery (está no segundo post do tópico, mas o fórum não permite que eu insira links).

Meu código é:

<script src="jquery.js" type="text/javascript"></script>

<script src="jquery.maskedinput.js" type="text/javascript"></script>

jQuery(function($){

&#036;(&quot;#rg&quot;).mask(&quot;9.999.999-9&quot;);

});

Porém não funcionou e é possível digitar letras, menos de 8 números e mais de 8. O campo CPF já estava com validação feita e pensei em me basear nele para fazer o do RG. Mas aquele campo valida entre CPF e CNPJ, logo, não me atende. O código é:

$(‘input[name=“Empresa[natureza]”]:radio’).click(function(){

&#036;(&quot;#Empresa_cpf_cnpj&quot;).mask((&#036;(this).val() == '1')? &quot;99.999.999/9999-99&quot; : &quot;999.999.999-99&quot;);

});

No PostgreSQL ambos os campos são do tipo character e com seus respectivos tamanhos: CPF(11) e RG( 8 ).

Estes códigos eu incluí nos arquivos admin.js e edit.js. Mas não sei o que preciso alterar em termos de arquivos de Model, View e Controll. Vi aqui no tópico que seria preciso incluir num arquivo do Model (dentro da public function rules) um validador, como o do cnpj: array(‘cnpj’, ‘ext.validators.CNPJValidatorName’). Mas não encontrei nenhum validador assim para rg.

Se alguém puder me ajudar, agradeço muito.

Só atualizando se alguém precisar validar um campo de RG, descobri que existem várias regras diferentes para o RG e por este motivo não é possível fazer esta validação. Meu coordenador também já me orientou a abortar esta missão.

Olá Newerton, tudo beleza ? Comecei a cerca de um mês no Yii2, ainda estou assistindo algumas aulas, porém um amigo conseguiu uma vaga pra trabalhar na empresa dele. Estou tentando fazer o mesmo processo que o pessoal basicamente, porém ainda não vamos usar verificadores, apenas a opção de escolher CPF ou CNPJ e fazendo com que assim abra um campo para digitar essas informações. Vou mandar o form que estamos usando.

<?php use yii\helpers\Html; use yii\widgets\ActiveForm; use yii\widgets\MaskedInput; /* @var $this yii\web\View */ /* @var $model app\models\Lead */ /* @var $form yii\widgets\ActiveForm */ ?>
<?php $form = ActiveForm::begin(); ?>

<?= $form->field($model, 'nome')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'tipo')->dropDownList(['' => 'Selecione', 'PF'=> 'Pessoa Física','PJ'=>'Pessoa Jurídica']) ?>

<?= $form->field($model, 'telefone')->widget(MaskedInput::class, [

    'mask' => '(99)99999-9999']) ?>



<?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>

<?php //echo $form->field($model, 'cpf_cnpj')->dropDownList(); ?>

<?= $form->field($model, 'meio_captacao')->dropDownList(['' => 'Selecione','0' => 'Visita presencial', '1' => 'Parceiro de vendas', '2' => 'Anúncio Google', '3' => 'Pesquisa no Google', '4' => 'Instagram', '5' => 'Facebook', '6' => 'Whatsapp', '7' => 'Telegram', '8' => 'Billboard (Outdoor)', '9' => 'Indicação de amigo', '10' => 'Carro de som', '11' => 'Faixa', '12' => 'Panfleto', '13' => 'Propaganda em parede', '14' => 'Comercial no rádio', '15' => 'Comercial na TV', '16' => 'Banner em um site', '17' => 'Carta proposta', '18' => 'Licitação', '19' => 'Outros']) ?>

<?= $form->field($model, 'cep')->widget(MaskedInput::class, [

    'mask' => '99999-999']) ?>

<?= $form->field($model, 'rua')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'numero')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'bairro')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'complemento')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'cidade_id')->textInput() ?>

<?= $form->field($model, 'forma_pagamento')->dropDownList(['' => 'Selecione','a vista' => 'Á vista', 'financiamento' => 'Financiamento', 'outra forma' => 'Outra forma']) ?>

<?= $form->field($model, 'obs_consumo')->textarea(['rows' => 6]) ?>

<?= $form->field($model, 'dt_apresenta')->textInput() ?>

<?= $form->field($model, 'hr_apresenta')->textInput() ?>

<div class="form-group">

        <?= Html::submitButton($model->isNewRecord ? 'Cadastrar' : 'Alterar', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

    </div>

<?php ActiveForm::end(); ?>

@Thearly , tudo bem? Então existe algumas formas de fazer isso, vai depender de como está modelado seu banco de dados. Vi que já tem um campo cpf_cnpj, o que você pode fazer é usar o widget MaskedInput nesse campo, assim você pode usar 2 máscaras em 1 campo só.

Exemplo:

$form->field($model, 'telefone')->widget(MaskedInput::class, [
'mask' => ['999.999.999-99', '99.999.999/9999-99']
]);

Desde modo você consegue usar CPF e CNPJ no mesmo campo. No caso do tipo, você usar ele para validar no Lead model. Usa o beforeValidate(), e verificar se o tipo é PF ou PJ, se for PF, usa o preg_match() com strlen() para validar o CPF, e depois valida o CNPJ com o mesmo raciocínio.

Parecido com isso:

$document = preg_replace('/\D/', '', $this->cpf_cnpj);
if($this->tipo === 'CPF' && strlen($document) !== 11){
    $this->addError('cpf_cnpj', 'CPF inválido');
}
if($this->tipo === 'CNPJ' && strlen($document) !== 14){
    $this->addError('cpf_cnpj', 'CNPJ inválido');
}

No meu caso, eu removeria esse tipo, e validação somente o cpf_cnpj usando alguma função que valida se o CPF/CNPJ é valido, para o usuário não adicionar qualquer número.