document.addEventListener('DOMContentLoaded', function() {
// Obtener elementos del DOM
const table = document.getElementById('employeeTable');
const tbody = table.querySelector('tbody');
const searchInput = document.getElementById('searchInput');
const departmentFilter = document.getElementById('departmentFilter');
const headers = table.querySelectorAll('th[data-sort]');
const prevPageBtn = document.getElementById('prevPage');
const nextPageBtn = document.getElementById('nextPage');
// Datos de ejemplo (en una aplicación real, esto vendría de una API)
const employees = [
{ name: "John Smith", department: "Ingeniería", position: "Desarrollador Senior", salary: "$95,000", joinDate: "2020-05-15" },
{ name: "Emily Johnson", department: "Marketing", position: "Gerente de Marketing", salary: "$85,000", joinDate: "2019-03-22" },
{ name: "Michael Brown", department: "Ventas", position: "Representante de Ventas", salary: "$65,000", joinDate: "2021-01-10" },
{ name: "Sarah Davis", department: "Ingeniería", position: "Desarrollador Frontend", salary: "$80,000", joinDate: "2020-11-05" },
{ name: "Robert Wilson", department: "RRHH", position: "Especialista en RRHH", salary: "$70,000", joinDate: "2018-07-19" },
{ name: "Jennifer Lee", department: "Ingeniería", position: "Desarrollador Backend", salary: "$90,000", joinDate: "2019-12-03" },
{ name: "David Miller", department: "Marketing", position: "Especialista de Contenido", salary: "$60,000", joinDate: "2021-03-17" },
{ name: "Lisa Anderson", department: "Ventas", position: "Gerente de Ventas", salary: "$95,000", joinDate: "2018-11-28" },
{ name: "James Taylor", department: "RRHH", position: "Reclutador", salary: "$65,000", joinDate: "2020-08-14" },
{ name: "Patricia Thomas", department: "Ingeniería", position: "Ingeniero DevOps", salary: "$100,000", joinDate: "2019-06-21" }
];
// Gestión de estado
let currentSort = { column: null, direction: 'asc' };
let currentFilter = { search: '', department: '' };
let currentPage = 1;
const recordsPerPage = 5;
// Inicializar la tabla
function initTable() {
renderTable();
setupEventListeners();
}
// Configurar escuchadores de eventos
function setupEventListeners() {
// Ordenación
headers.forEach(header => {
header.addEventListener('click', () => {
const column = header.getAttribute('data-sort');
handleSort(column);
});
});
// Búsqueda
searchInput.addEventListener('input', () => {
currentFilter.search = searchInput.value.toLowerCase();
currentPage = 1;
renderTable();
});
// Filtrado
departmentFilter.addEventListener('change', () => {
currentFilter.department = departmentFilter.value;
currentPage = 1;
renderTable();
});
// Paginación
prevPageBtn.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderTable();
}
});
nextPageBtn.addEventListener('click', () => {
const totalPages = Math.ceil(getFilteredData().length / recordsPerPage);
if (currentPage < totalPages) {
currentPage++;
renderTable();
}
});
}
// Manejar ordenación
function handleSort(column) {
// Restablecer indicadores de ordenación
headers.forEach(header => {
header.classList.remove('sort-asc', 'sort-desc');
});
// Determinar dirección de ordenación
if (currentSort.column === column) {
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
} else {
currentSort.column = column;
currentSort.direction = 'asc';
}
// Agregar indicador de ordenación al encabezado clickeado
const header = table.querySelector(`th[data-sort="${column}"]`);
header.classList.add(currentSort.direction === 'asc' ? 'sort-asc' : 'sort-desc');
renderTable();
}
// Obtener datos filtrados
function getFilteredData() {
return employees.filter(employee => {
const matchesSearch =
currentFilter.search === '' ||
employee.name.toLowerCase().includes(currentFilter.search) ||
employee.position.toLowerCase().includes(currentFilter.search);
const matchesDepartment =
currentFilter.department === '' ||
employee.department === currentFilter.department;
return matchesSearch && matchesDepartment;
});
}
// Ordenar datos
function getSortedData(data) {
if (!currentSort.column) return data;
return [...data].sort((a, b) => {
const aVal = a[currentSort.column];
const bVal = b[currentSort.column];
// Manejar valores numéricos
if (currentSort.column === 'salary') {
const aNum = parseInt(aVal.replace(/[^0-9]/g, ''));
const bNum = parseInt(bVal.replace(/[^0-9]/g, ''));
return currentSort.direction === 'asc' ? aNum - bNum : bNum - aNum;
}
// Manejar valores de fecha
if (currentSort.column === 'joinDate') {
return currentSort.direction === 'asc' ?
new Date(aVal) - new Date(bVal) :
new Date(bVal) - new Date(aVal);
}
// Manejar valores de texto
if (aVal < bVal) return currentSort.direction === 'asc' ? -1 : 1;
if (aVal > bVal) return currentSort.direction === 'asc' ? 1 : -1;
return 0;
});
}
// Renderizar tabla
function renderTable() {
// Mostrar estado de carga
const container = document.querySelector('.data-table-container');
container.classList.add('loading');
// Simular retraso de API
setTimeout(() => {
// Obtener datos filtrados y ordenados
let filteredData = getFilteredData();
const totalRecords = filteredData.length;
filteredData = getSortedData(filteredData);
// Calcular paginación
const totalPages = Math.ceil(totalRecords / recordsPerPage);
const startIndex = (currentPage - 1) * recordsPerPage;
const endIndex = Math.min(startIndex + recordsPerPage, totalRecords);
const pageData = filteredData.slice(startIndex, endIndex);
// Renderizar filas de la tabla
tbody.innerHTML = '';
pageData.forEach(employee => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${employee.name}</td>
<td>${employee.department}</td>
<td>${employee.position}</td>
<td>${employee.salary}</td>
<td>${employee.joinDate}</td>
`;
tbody.appendChild(row);
});
// Actualizar información de paginación
document.getElementById('startRecord').textContent = startIndex + 1;
document.getElementById('endRecord').textContent = endIndex;
document.getElementById('totalRecords').textContent = totalRecords;
// Actualizar botones de paginación
prevPageBtn.disabled = currentPage === 1;
nextPageBtn.disabled = currentPage === totalPages || totalPages === 0;
// Actualizar visualización de números de página
const pageNumbers = document.querySelector('.page-numbers');
pageNumbers.innerHTML = '';
for (let i = 1; i <= totalPages; i++) {
const pageSpan = document.createElement('span');
pageSpan.textContent = i;
pageSpan.className = i === currentPage ? 'current-page' : 'page-number';
if (i !== currentPage) {
pageSpan.addEventListener('click', () => {
currentPage = i;
renderTable();
});
}
pageNumbers.appendChild(pageSpan);
}
// Ocultar estado de carga
container.classList.remove('loading');
}, 300);
}
// Inicializar la tabla
initTable();
});