feat: Melhorias de segurança e interface - Segurança: Implementação de CSRF token em formulários, validação no backend, proteção AJAX - QR Code: Preservação do otp_secret, evita geração desnecessária - Interface: Correções visuais, padronização de cores, melhorias em formulários
This commit is contained in:
@@ -7,6 +7,13 @@
|
||||
--green: #198754;
|
||||
--cyan: #0dcaf0;
|
||||
--yellow: #ffc107;
|
||||
--primary-color: #dc3545;
|
||||
--primary-hover: #bb2d3b;
|
||||
--text-color: #333;
|
||||
--text-muted: #6c757d;
|
||||
--bg-hover: #f8f9fa;
|
||||
--tab-active-color: var(--primary-color);
|
||||
--tab-hover-color: rgba(220, 53, 69, 0.1);
|
||||
}
|
||||
|
||||
/* Tabelas */
|
||||
@@ -241,4 +248,171 @@
|
||||
.welcome-header h4 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.nav-tabs {
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link,
|
||||
.nav-tabs .nav-link:focus,
|
||||
.nav-tabs .nav-link:hover,
|
||||
.nav-tabs .nav-link.active {
|
||||
color: var(--primary-color) !important;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-bottom: -2px;
|
||||
transition: all 0.2s ease-in-out;
|
||||
font-weight: 500;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link:hover {
|
||||
background-color: var(--tab-hover-color);
|
||||
border-bottom: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
font-weight: 600;
|
||||
background-color: var(--tab-hover-color);
|
||||
border-bottom: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link i {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.tab-pane {
|
||||
animation: fadeIn 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsividade das abas */
|
||||
@media (max-width: 768px) {
|
||||
.nav-tabs {
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
white-space: nowrap;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Estilo para botões com largura fixa */
|
||||
.btn-fixed-width {
|
||||
min-width: 120px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.375rem 0.75rem;
|
||||
text-align: center;
|
||||
height: 38px;
|
||||
line-height: 1.5;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-fixed-width i {
|
||||
margin-right: 8px;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
/* Estilo para o backdrop com blur em todos os modais */
|
||||
.modal-backdrop.show {
|
||||
backdrop-filter: blur(8px);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* Estilo para o botão de fechar dos modais */
|
||||
.btn-close {
|
||||
background-color: transparent;
|
||||
padding: 0.5rem;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s;
|
||||
filter: invert(1) grayscale(100%) brightness(200%);
|
||||
}
|
||||
|
||||
.btn-close:hover {
|
||||
opacity: 1;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* Estilos do Modal */
|
||||
.modal-header {
|
||||
background-color: #343a40;
|
||||
color: #fff;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-header i {
|
||||
color: #fff;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.modal-header .btn-close {
|
||||
filter: invert(1) grayscale(100%) brightness(200%);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.modal-header .btn-close:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Estilos globais de formulário */
|
||||
.form-control:focus,
|
||||
.form-select:focus,
|
||||
.form-check-input:focus,
|
||||
.btn:focus,
|
||||
.btn-check:focus + .btn {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
|
||||
}
|
||||
|
||||
.form-control:hover,
|
||||
.form-select:hover {
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* Input group com foco */
|
||||
.input-group .form-control:focus,
|
||||
.input-group .form-select:focus {
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* Checkbox e radio */
|
||||
.form-check-input:checked {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* Date picker */
|
||||
input[type="date"]:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
|
||||
}
|
||||
@@ -61,6 +61,8 @@ function filtrarMilitantes() {
|
||||
|
||||
// Configurar eventos quando o DOM estiver carregado
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('DOM carregado, configurando eventos...');
|
||||
|
||||
// Configurar pesquisa
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
if (searchInput) {
|
||||
@@ -109,7 +111,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
});
|
||||
|
||||
console.log('DOM carregado');
|
||||
console.log('Configurando modal de edição...');
|
||||
|
||||
// Configuração do modal de edição
|
||||
const modalEditarMilitante = document.getElementById('modalEditarMilitante');
|
||||
@@ -118,6 +120,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
if (modalEditarMilitante) {
|
||||
console.log('Modal encontrado, configurando eventos...');
|
||||
|
||||
// Criar instância do modal Bootstrap
|
||||
const modalInstance = new bootstrap.Modal(modalEditarMilitante);
|
||||
console.log('Instância do modal criada:', modalInstance);
|
||||
|
||||
modalEditarMilitante.addEventListener('show.bs.modal', function(event) {
|
||||
console.log('Modal sendo exibido');
|
||||
const button = event.relatedTarget;
|
||||
@@ -129,33 +135,155 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
const militanteId = button.getAttribute('data-militante-id');
|
||||
const militanteNome = button.getAttribute('data-militante-nome');
|
||||
console.log('ID do militante:', militanteId);
|
||||
console.log('Nome do militante:', militanteNome);
|
||||
|
||||
// Dados do militante
|
||||
const dados = {
|
||||
nome: button.getAttribute('data-militante-nome'),
|
||||
cpf: button.getAttribute('data-militante-cpf'),
|
||||
email: button.getAttribute('data-militante-email'),
|
||||
telefone: button.getAttribute('data-militante-telefone'),
|
||||
endereco: button.getAttribute('data-militante-endereco'),
|
||||
filiado: button.getAttribute('data-militante-filiado')
|
||||
};
|
||||
console.log('Dados do militante:', dados);
|
||||
if (!militanteId) {
|
||||
console.error('ID do militante não encontrado no botão!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Preencher campos
|
||||
document.getElementById('editNome').value = dados.nome || '';
|
||||
document.getElementById('editCpf').value = dados.cpf || '';
|
||||
document.getElementById('editEmail').value = dados.email || '';
|
||||
document.getElementById('editTelefone').value = dados.telefone || '';
|
||||
document.getElementById('editEndereco').value = dados.endereco || '';
|
||||
document.getElementById('editFiliado').checked = dados.filiado === 'True';
|
||||
// Atualizar o título do modal com o nome do militante
|
||||
const modalTitle = modalEditarMilitante.querySelector('.modal-title');
|
||||
if (modalTitle) {
|
||||
modalTitle.innerHTML = `<i class="fas fa-user-edit me-2"></i>Editar ${militanteNome}`;
|
||||
}
|
||||
|
||||
// Configurar formulário
|
||||
const form = document.getElementById('formEditarMilitante');
|
||||
if (form) {
|
||||
form.action = `/militantes/editar/${militanteId}`;
|
||||
const idInput = document.getElementById('edit_militante_id');
|
||||
if (idInput) {
|
||||
idInput.value = militanteId;
|
||||
}
|
||||
console.log('Action do formulário:', form.action);
|
||||
console.log('ID do militante no formulário:', militanteId);
|
||||
} else {
|
||||
console.error('Formulário não encontrado!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Mostrar loading
|
||||
const modalBody = modalEditarMilitante.querySelector('.modal-body');
|
||||
if (modalBody) {
|
||||
modalBody.style.opacity = '0.5';
|
||||
}
|
||||
|
||||
// Buscar dados completos do militante via AJAX
|
||||
console.log(`Fazendo requisição para /militantes/${militanteId}/dados`);
|
||||
|
||||
// Obter o CSRF token
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
console.log('CSRF token:', csrfToken);
|
||||
|
||||
fetch(`/militantes/${militanteId}/dados`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Resposta recebida:', response);
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.message || `HTTP error! status: ${response.status}`);
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(dados => {
|
||||
console.log('Dados do militante recebidos:', dados);
|
||||
|
||||
if (!dados) {
|
||||
throw new Error('Dados do militante não encontrados');
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Preenchendo dados básicos...');
|
||||
// Dados Básicos
|
||||
document.getElementById('edit_nome').value = dados.nome || '';
|
||||
document.getElementById('edit_cpf').value = dados.cpf || '';
|
||||
document.getElementById('edit_titulo_eleitoral').value = dados.titulo_eleitoral || '';
|
||||
document.getElementById('edit_data_nascimento').value = dados.data_nascimento || '';
|
||||
document.getElementById('edit_data_entrada').value = dados.data_entrada_oci || '';
|
||||
document.getElementById('edit_data_efetivacao').value = dados.data_efetivacao_oci || '';
|
||||
console.log('Dados básicos preenchidos');
|
||||
|
||||
console.log('Preenchendo dados de contato...');
|
||||
// Contato
|
||||
document.getElementById('edit_telefone1').value = dados.telefone1 || '';
|
||||
document.getElementById('edit_telefone2').value = dados.telefone2 || '';
|
||||
document.getElementById('edit_email').value = dados.email || '';
|
||||
console.log('Dados de contato preenchidos');
|
||||
|
||||
console.log('Preenchendo dados de endereço...');
|
||||
// Endereço
|
||||
if (dados.endereco) {
|
||||
document.getElementById('edit_cep').value = dados.endereco.cep || '';
|
||||
document.getElementById('edit_estado').value = dados.endereco.estado || '';
|
||||
document.getElementById('edit_cidade').value = dados.endereco.cidade || '';
|
||||
document.getElementById('edit_bairro').value = dados.endereco.bairro || '';
|
||||
document.getElementById('edit_logradouro').value = dados.endereco.rua || '';
|
||||
document.getElementById('edit_numero').value = dados.endereco.numero || '';
|
||||
document.getElementById('edit_complemento').value = dados.endereco.complemento || '';
|
||||
}
|
||||
console.log('Dados de endereço preenchidos');
|
||||
|
||||
console.log('Preenchendo dados profissionais...');
|
||||
// Profissional
|
||||
document.getElementById('edit_profissao').value = dados.profissao || '';
|
||||
document.getElementById('edit_regime_trabalho').value = dados.regime_trabalho || '';
|
||||
document.getElementById('edit_empresa').value = dados.empresa || '';
|
||||
document.getElementById('edit_contratante').value = dados.contratante || '';
|
||||
console.log('Dados profissionais preenchidos');
|
||||
|
||||
console.log('Preenchendo dados acadêmicos...');
|
||||
// Acadêmico
|
||||
document.getElementById('edit_instituicao_ensino').value = dados.instituicao_ensino || '';
|
||||
document.getElementById('edit_tipo_instituicao').value = dados.tipo_instituicao || '';
|
||||
console.log('Dados acadêmicos preenchidos');
|
||||
|
||||
console.log('Preenchendo dados sindicais...');
|
||||
// Sindical
|
||||
document.getElementById('edit_sindicato').value = dados.sindicato || '';
|
||||
document.getElementById('edit_cargo_sindical').value = dados.cargo_sindical || '';
|
||||
document.getElementById('edit_central_sindical').value = dados.central_sindical || '';
|
||||
document.getElementById('edit_dirigente_sindical').checked = dados.dirigente_sindical || false;
|
||||
console.log('Dados sindicais preenchidos');
|
||||
|
||||
console.log('Preenchendo dados organizacionais...');
|
||||
// Organização
|
||||
document.getElementById('edit_estado_militante').value = dados.estado || 'ATIVO';
|
||||
document.getElementById('edit_celula').value = dados.celula_id || '';
|
||||
|
||||
// Responsabilidades
|
||||
const responsabilidades = dados.responsabilidades || 0;
|
||||
document.querySelectorAll('input[name="responsabilidades"]').forEach(checkbox => {
|
||||
const valor = parseInt(checkbox.value);
|
||||
checkbox.checked = (responsabilidades & valor) !== 0;
|
||||
});
|
||||
console.log('Dados organizacionais preenchidos');
|
||||
|
||||
console.log('Todos os dados preenchidos com sucesso!');
|
||||
} catch (error) {
|
||||
console.error('Erro ao preencher os campos:', error);
|
||||
throw new Error('Erro ao preencher os dados do militante: ' + error.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao buscar dados do militante:', error);
|
||||
alert('Erro ao carregar dados do militante: ' + error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
if (modalBody) {
|
||||
modalBody.style.opacity = '1';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Envio do formulário de edição via AJAX
|
||||
@@ -163,53 +291,76 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
if (formEditarMilitante) {
|
||||
formEditarMilitante.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
console.log('Enviando formulário de edição...');
|
||||
|
||||
const formData = new FormData(this);
|
||||
console.log('Dados do formulário:', Object.fromEntries(formData));
|
||||
|
||||
fetch(this.action, {
|
||||
// Adicionar responsabilidades selecionadas
|
||||
const responsabilidades = Array.from(this.querySelectorAll('input[name="responsabilidades"]:checked'))
|
||||
.map(cb => parseInt(cb.value))
|
||||
.reduce((a, b) => a + b, 0);
|
||||
formData.set('responsabilidades', responsabilidades);
|
||||
|
||||
// Obter o CSRF token
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
console.log('CSRF token:', csrfToken);
|
||||
|
||||
// Obter o ID do militante do campo hidden
|
||||
const militanteId = document.getElementById('edit_militante_id').value;
|
||||
console.log('ID do militante:', militanteId);
|
||||
|
||||
if (!militanteId) {
|
||||
console.error('ID do militante não encontrado!');
|
||||
mostrarAlerta('Erro: ID do militante não encontrado', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
// Garantir que o campo de endereço está correto
|
||||
const logradouro = formData.get('logradouro');
|
||||
if (logradouro) {
|
||||
formData.set('rua', logradouro);
|
||||
formData.delete('logradouro');
|
||||
}
|
||||
|
||||
fetch(`/militantes/editar/${militanteId}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Resposta recebida:', response);
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.message || `HTTP error! status: ${response.status}`);
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Resposta processada:', data);
|
||||
if (data.status === 'success') {
|
||||
// Fechar o modal
|
||||
bootstrap.Modal.getInstance(modalEditarMilitante).hide();
|
||||
|
||||
// Atualizar a lista
|
||||
location.reload();
|
||||
|
||||
// Mostrar mensagem de sucesso
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-success alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
${data.message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.container').insertBefore(alertDiv, document.querySelector('.container').firstChild);
|
||||
mostrarAlerta(data.message, 'success');
|
||||
|
||||
// Recarregar a página após um breve delay
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1500);
|
||||
} else {
|
||||
// Mostrar erro
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-danger alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
${data.message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.modal-body').insertBefore(alertDiv, formEditarMilitante);
|
||||
throw new Error(data.message || 'Erro ao salvar dados');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro:', error);
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-danger alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
Erro ao atualizar militante. Tente novamente.
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.modal-body').insertBefore(alertDiv, formEditarMilitante);
|
||||
console.error('Erro ao enviar formulário:', error);
|
||||
mostrarAlerta(`Erro ao salvar dados: ${error.message}`, 'danger');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -334,32 +485,31 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// Máscara para CPF
|
||||
const cpfInput = document.getElementById('cpf');
|
||||
if (cpfInput) {
|
||||
cpfInput.addEventListener('input', function(e) {
|
||||
const cpfInputs = document.querySelectorAll('input[name="cpf"]');
|
||||
cpfInputs.forEach(input => {
|
||||
input.addEventListener('input', function(e) {
|
||||
let value = e.target.value.replace(/\D/g, '');
|
||||
if (value.length <= 11) {
|
||||
value = value.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
|
||||
value = value.replace(/(\d{3})(\d)/, '$1.$2');
|
||||
value = value.replace(/(\d{3})(\d)/, '$1.$2');
|
||||
value = value.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
|
||||
e.target.value = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Máscara para telefone
|
||||
const telefoneInput = document.getElementById('telefone');
|
||||
if (telefoneInput) {
|
||||
telefoneInput.addEventListener('input', function(e) {
|
||||
const telefoneInputs = document.querySelectorAll('input[name="telefone1"], input[name="telefone2"]');
|
||||
telefoneInputs.forEach(input => {
|
||||
input.addEventListener('input', function(e) {
|
||||
let value = e.target.value.replace(/\D/g, '');
|
||||
if (value.length <= 11) {
|
||||
if (value.length === 11) {
|
||||
value = value.replace(/(\d{2})(\d{5})(\d{4})/, '($1) $2-$3');
|
||||
} else {
|
||||
value = value.replace(/(\d{2})(\d{4})(\d{4})/, '($1) $2-$3');
|
||||
}
|
||||
value = value.replace(/(\d{2})(\d)/, '($1) $2');
|
||||
value = value.replace(/(\d{4,5})(\d{4})$/, '$1-$2');
|
||||
e.target.value = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Limpar formulário e alertas quando o modal for fechado
|
||||
const modalNovoMilitante = document.getElementById('modalNovoMilitante');
|
||||
@@ -444,4 +594,71 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
document.body.removeChild(link);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Configurar máscaras de input
|
||||
// CEP
|
||||
const cepInputs = document.querySelectorAll('input[name="cep"]');
|
||||
cepInputs.forEach(input => {
|
||||
input.addEventListener('input', function(e) {
|
||||
let value = e.target.value.replace(/\D/g, '');
|
||||
if (value.length <= 8) {
|
||||
value = value.replace(/(\d{5})(\d)/, '$1-$2');
|
||||
e.target.value = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Buscar endereço pelo CEP
|
||||
input.addEventListener('blur', function(e) {
|
||||
const cep = e.target.value.replace(/\D/g, '');
|
||||
if (cep.length === 8) {
|
||||
fetch(`https://viacep.com.br/ws/${cep}/json/`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.erro) {
|
||||
const form = input.closest('form');
|
||||
form.querySelector('input[name="logradouro"]').value = data.logradouro;
|
||||
form.querySelector('input[name="bairro"]').value = data.bairro;
|
||||
form.querySelector('input[name="cidade"]').value = data.localidade;
|
||||
form.querySelector('select[name="estado"]').value = data.uf;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Título Eleitoral
|
||||
const tituloInputs = document.querySelectorAll('input[name="titulo_eleitoral"]');
|
||||
tituloInputs.forEach(input => {
|
||||
input.addEventListener('input', function(e) {
|
||||
let value = e.target.value.replace(/\D/g, '');
|
||||
if (value.length <= 12) {
|
||||
value = value.replace(/(\d{4})(\d)/, '$1 $2');
|
||||
value = value.replace(/(\d{4})(\d)/, '$1 $2');
|
||||
e.target.value = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Função para mostrar alertas
|
||||
function mostrarAlerta(mensagem, tipo) {
|
||||
// Criar o elemento de alerta
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = `alert alert-${tipo} alert-dismissible fade show position-fixed top-0 start-50 translate-middle-x mt-3`;
|
||||
alertDiv.style.zIndex = '9999';
|
||||
alertDiv.innerHTML = `
|
||||
${mensagem}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
|
||||
// Adicionar o alerta ao corpo do documento
|
||||
document.body.appendChild(alertDiv);
|
||||
|
||||
// Configurar o Bootstrap alert
|
||||
const bsAlert = new bootstrap.Alert(alertDiv);
|
||||
|
||||
// Remover o alerta após 3 segundos
|
||||
setTimeout(() => {
|
||||
bsAlert.close();
|
||||
}, 3000);
|
||||
}
|
||||
Reference in New Issue
Block a user