Porque jQuery Mask não valida os campos criados programaticamente com JS?

Boa tarde, devs!

Eu tenho um formulário HTML de cadastro de clientes. O primeiro campo deste formulário é um select (combobox), com o qual eu quero especificar o tipo de cliente (Pessoa Física ou Pessoa Jurídica).

De acordo com a opção selecionada no combobox, eu crio os campos específicos para aquele tipo de cliente.

Na minha marcação HTML, Pessoa Física já está escolhida, bem como os campos específicos deste tipo (Nome, CPF, RG e Nascimento). Quando eu escolho Pessoa Jurídica, meu script JS localiza a marcação HTML com os campos de PF e destrói-os (não dá um “hide”, remove do DOM mesmo!), em seguida cria marcação para os campos de PJ (Nome Fantasia, CNPJ, Razão Social, Inscrição Municipal e Inscrição SUFRAMA) e insere no DOM.

Tudo renderiza na tela conforme o esperado. Mesmo quando eu alterno de um valor para o outro, tudo ocorre perfeitamente: os campos de um somem e são criados os do outro. Detalhe importante: estou utilizando o plugin de máscara jQuery para validar alguns campos fiscais/legais que têm formatos específicos (CPF, CEP, CNPJ, inscrições, etc).

O problema agora mora aqui: o plugin não consegue aplicar a máscara aos campos que eu criei com o código javascript. Quando eu altero o tipo do cliente uma vez, a máscara deixa de funcionar definitivamente em qualquer campo que eu queira validar.

Gostaria que alguém me ajudasse a validar esses campos. Eu desenvolvi com JS puro e procuro uma solução sem o uso de frameworks, pois não sei usá-los, estou aprendendo JS na unha.

Meu contato, caso precise, para eu explicar algum detalhe: (87) 99646-7409.
Fico muito grato se alguém puder me ajudar nessa.

Segue o código HTML da página (index.html):

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Cadastro</title>
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<link rel="stylesheet" href="css/bootstrap.min.css">
	<link rel="stylesheet" href="css/styles.min.css">
</head>
<body>
	<div class="container">
		<div class="row">
			<form id="formCadastro">
				<div class="form-group linhaTipo">
					<label for="tipo">Tipo de cliente</label>
					<select name="tipo" id="tipo" class="form-control">
						<option value="1">Pessoa Física</option>
						<option value="2">Pessoa Jurídica</option>
					</select>
				</div>

				<div class="form-group linhaNome">
					<label for="name">Nome</label>
					<input type="text" name="name" id="name" class="form-control">
				</div>

				<div class="form-group linhaCpf">
					<label for="cpf">CPF</label>
					<input type="text" name="cpf" id="cpf" class="form-control">
				</div>

				<div class="form-group linhaRg">
					<label for="rg">RG</label>
					<input type="text" name="rg" id="rg" class="form-control">
				</div>

				<div class="form-group linhaNascimento">
					<label for="birthDate">Nascimento</label>
					<input type="date" name="birthDate" id="birthDate" class="form-control">
				</div>
				
				<div class="form-group linhaFone">
					<label for="fone">Telefone</label>
					<input type="tel" name="fone" id="fone" class="form-control">
				</div>

				<div class="form-group">
					<button type="submit" class="btn btn-primary">
						Enviar
					</button>
				</div>
			</form>
		</div><!-- .row -->
	</div><!-- .container -->

	<script src="js/jquery.min.js"></script>
	<script src="js/bootstrap.min.js"></script>
	<script src="js/jquery.mask.min.js"></script>
	<script src="js/escolheTipoCliente.js"></script>
	<script>
		$(document).ready(function(){
			// validando apenas alguns campos de PF (deixa de funcionar quando se altera o tipo do usuário)
			$('#cpf').mask('000.000.000-00', {reverse: true});
			$('#rg').mask('0.000.000', {reverse: true});
		});
	</script>
</body>
</html>

Agora o script contendo toda a lógica JS (escolheTipoCliente.js):

window.onload = init;

function init() {
	var tipo = document.querySelector('#tipo');

	tipo.addEventListener('change', function(e) {
		var form = document.querySelector('#formCadastro');

		this.linhaFone = form.querySelector('.linhaFone');	// insere no nó antes desse elemento (.insertBefor())

		if (e.target.value == 1) {
			// destrói os elementos de PJ
			form.removeChild(document.querySelector('.linhaNomeFantasia'));
			form.removeChild(document.querySelector('.linhaCnpj'));
			form.removeChild(document.querySelector('.linhaRazaoSocial'));
			form.removeChild(document.querySelector('.linhaInscricaoMunicipal'));
			form.removeChild(document.querySelector('.linhaInscricaoSuframa'));
			form.removeChild(document.querySelector('.linhaResponsavel'));

			// cria os elementos de PF
			criaLinha('div', 'linhaNome', 'name', 'Nome', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaCpf', 'cpf', 'CPF', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaRg', 'rg', 'RG', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaNascimento', 'birthDate', 'Nascimento', 'date', form, this.linhaFone);
		} else {
			// destrói os elementos de PF
			form.removeChild(document.querySelector('.linhaNome'));
			form.removeChild(document.querySelector('.linhaCpf'));
			form.removeChild(document.querySelector('.linhaRg'));
			form.removeChild(document.querySelector('.linhaNascimento'));

			// cria os elementos de PJ
			criaLinha('div', 'linhaNomeFantasia', 'nomeFantasia', 'Nome Fantasia', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaCnpj', 'cnpj', 'CNPJ', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaRazaoSocial', 'razaoSocial', 'Razão Social', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaInscricaoMunicipal', 'inscricaoMunicipal', 'Inscrição Municipal', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaInscricaoSuframa', 'inscricaoSuframa', 'Inscrição SUFRAMA', 'text', form, this.linhaFone);
			criaLinha('div', 'linhaResponsavel', 'responsavel', 'Responsável', 'text', form, this.linhaFone);
		}
	});

	// cria todo o container de um campo específico
	function criaLinha(elemento, linhaCampo, nomeRotulo, valorRotulo, campoTipo, form, before) {
		// div.form-group
		var el = document.createElement(elemento);
		el.classList.add('form-group');
		el.classList.add(linhaCampo);
		form.insertBefore(el, before);

		// label para o input.form-control
		var label = document.createElement('label');
		label.setAttribute('for', nomeRotulo);
		label.textContent = valorRotulo;
		el.appendChild(label);

		// input.form-control
		var campo = document.createElement('input');
		campo.setAttribute('type', campoTipo);
		campo.setAttribute('name', nomeRotulo);
		campo.setAttribute('id', nomeRotulo);
		campo.classList.add('form-control');
		el.appendChild(campo);
	}
};

vc tem que aplicar a mascara novamente cada vez que criar os campos no DOM.

isole esse trecho de código em uma função
function mascaras(){
$(’#cpf’).mask(‘000.000.000-00’, {reverse: true});
$(’#rg’).mask(‘0.000.000’, {reverse: true});
}

e chame ela apos da o appendChild com os elementos no DOM
tipo
appendChild(“seus inputs”);
mascaras();

1 curtida

Valeu, @Fabio_Dos_Reis! Deu tudo certinho! Abraço!