145 lines
5.4 KiB
JavaScript
145 lines
5.4 KiB
JavaScript
// Máscaras para campos de formulário
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Máscara para CPF
|
|
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");
|
|
e.target.value = value;
|
|
}
|
|
});
|
|
});
|
|
|
|
// Máscara para telefone
|
|
const phoneInputs = document.querySelectorAll('input[name="telefone"]');
|
|
phoneInputs.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");
|
|
}
|
|
e.target.value = value;
|
|
}
|
|
});
|
|
});
|
|
|
|
// Formatação de valores monetários
|
|
const moneyInputs = document.querySelectorAll('input[type="number"][step="0.01"]');
|
|
moneyInputs.forEach(input => {
|
|
input.addEventListener('blur', function(e) {
|
|
const value = parseFloat(e.target.value);
|
|
if (!isNaN(value)) {
|
|
e.target.value = value.toFixed(2);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// Funções para tabelas
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const tables = document.querySelectorAll('.table');
|
|
tables.forEach(table => {
|
|
// Ordenação
|
|
const headers = table.querySelectorAll('th[data-sort]');
|
|
headers.forEach(header => {
|
|
header.addEventListener('click', function() {
|
|
const column = this.dataset.sort;
|
|
const asc = this.classList.toggle('sort-asc');
|
|
const tbody = table.querySelector('tbody');
|
|
const rows = Array.from(tbody.querySelectorAll('tr'));
|
|
|
|
rows.sort((a, b) => {
|
|
const aVal = a.querySelector(`td[data-${column}]`).dataset[column];
|
|
const bVal = b.querySelector(`td[data-${column}]`).dataset[column];
|
|
return asc ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
|
});
|
|
|
|
rows.forEach(row => tbody.appendChild(row));
|
|
});
|
|
});
|
|
|
|
// Filtro
|
|
const filterInput = document.querySelector(`#filter-${table.id}`);
|
|
if (filterInput) {
|
|
filterInput.addEventListener('input', function() {
|
|
const searchTerm = this.value.toLowerCase();
|
|
const rows = table.querySelectorAll('tbody tr');
|
|
|
|
rows.forEach(row => {
|
|
const text = row.textContent.toLowerCase();
|
|
row.style.display = text.includes(searchTerm) ? '' : 'none';
|
|
});
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// Validação de formulários
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const forms = document.querySelectorAll('form');
|
|
forms.forEach(form => {
|
|
form.addEventListener('submit', function(e) {
|
|
if (!form.checkValidity()) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
// Destacar campos inválidos
|
|
const invalidInputs = form.querySelectorAll(':invalid');
|
|
invalidInputs.forEach(input => {
|
|
input.classList.add('is-invalid');
|
|
|
|
// Adicionar mensagem de erro
|
|
const feedback = document.createElement('div');
|
|
feedback.className = 'invalid-feedback';
|
|
feedback.textContent = input.validationMessage;
|
|
input.parentNode.appendChild(feedback);
|
|
});
|
|
}
|
|
|
|
form.classList.add('was-validated');
|
|
});
|
|
});
|
|
});
|
|
|
|
// Animações e feedback visual
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Animar cards ao carregar
|
|
const cards = document.querySelectorAll('.card');
|
|
cards.forEach((card, index) => {
|
|
card.style.opacity = '0';
|
|
card.style.transform = 'translateY(20px)';
|
|
setTimeout(() => {
|
|
card.style.transition = 'all 0.3s ease';
|
|
card.style.opacity = '1';
|
|
card.style.transform = 'translateY(0)';
|
|
}, index * 100);
|
|
});
|
|
|
|
// Feedback visual para ações
|
|
const actionButtons = document.querySelectorAll('[data-action]');
|
|
actionButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
button.classList.add('animate__animated', 'animate__pulse');
|
|
setTimeout(() => {
|
|
button.classList.remove('animate__animated', 'animate__pulse');
|
|
}, 1000);
|
|
});
|
|
});
|
|
});
|
|
|
|
// Confirmações de ações
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const deleteButtons = document.querySelectorAll('[data-confirm]');
|
|
deleteButtons.forEach(button => {
|
|
button.addEventListener('click', function(e) {
|
|
if (!confirm(this.dataset.confirm)) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
});
|