Lista de Datos Avanzada con Filtrado y Ordenamiento

Avanzado

Un componente completo de lista de datos con filtrado avanzado, ordenamiento multi-columna, búsqueda inteligente, paginación, selección de filas, funcionalidad de exportación y gestión de columnas.

Vista Previa en Vivo

Implementación del Código

HTML
<div class="data-list-container">
  <!-- Header Section -->
  <div class="data-list-header">
    <div class="header-content">
      <h2 class="list-title">Directorio de Empleados</h2>
      <p class="list-description">Gestiona y visualiza información de empleados con filtrado y ordenamiento avanzado</p>
    </div>
    
    <!-- Action Buttons -->
    <div class="header-actions">
      <button class="btn btn-secondary" id="columnToggle">
        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
          <line x1="9" y1="9" x2="15" y2="9"></line>
          <line x1="9" y1="15" x2="15" y2="15"></line>
        </svg>
        Columnas
      </button>
      <button class="btn btn-secondary" id="exportData">
        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
          <polyline points="7,10 12,15 17,10"></polyline>
          <line x1="12" y1="15" x2="12" y2="3"></line>
        </svg>
        Exportar
      </button>
      <button class="btn btn-primary" id="addNew">
        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <line x1="12" y1="5" x2="12" y2="19"></line>
          <line x1="5" y1="12" x2="19" y2="12"></line>
        </svg>
        Agregar Empleado
      </button>
    </div>
  </div>

  <!-- Filters Section -->
  <div class="filters-section">
    <!-- Search Bar -->
    <div class="search-container">
      <div class="search-input-wrapper">
        <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <circle cx="11" cy="11" r="8"></circle>
          <path d="m21 21-4.35-4.35"></path>
        </svg>
        <input 
          type="text" 
          id="globalSearch" 
          class="search-input" 
          placeholder="Buscar empleados..."
          aria-label="Buscar empleados"
        >
        <button class="search-clear" id="searchClear" aria-label="Limpiar búsqueda">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
    </div>

    <!-- Advanced Filters -->
    <div class="advanced-filters">
      <div class="filter-group">
        <label for="departmentFilter">Departamento</label>
        <select id="departmentFilter" class="filter-select">
          <option value="">Todos los Departamentos</option>
          <option value="engineering">Ingeniería</option>
          <option value="marketing">Marketing</option>
          <option value="sales">Ventas</option>
          <option value="hr">Recursos Humanos</option>
          <option value="finance">Finanzas</option>
        </select>
      </div>

      <div class="filter-group">
        <label for="statusFilter">Estado</label>
        <select id="statusFilter" class="filter-select">
          <option value="">Todos los Estados</option>
          <option value="active">Activo</option>
          <option value="inactive">Inactivo</option>
          <option value="pending">Pendiente</option>
        </select>
      </div>

      <div class="filter-group">
        <label for="locationFilter">Ubicación</label>
        <select id="locationFilter" class="filter-select">
          <option value="">Todas las Ubicaciones</option>
          <option value="madrid">Madrid</option>
          <option value="barcelona">Barcelona</option>
          <option value="valencia">Valencia</option>
          <option value="remoto">Remoto</option>
        </select>
      </div>

      <div class="filter-group">
        <label for="hireDateFrom">Fecha de Contratación Desde</label>
        <input type="date" id="hireDateFrom" class="filter-input">
      </div>

      <div class="filter-group">
        <label for="hireDateTo">Fecha de Contratación Hasta</label>
        <input type="date" id="hireDateTo" class="filter-input">
      </div>

      <button class="btn btn-secondary" id="clearFilters">
        Limpiar Filtros
      </button>
    </div>
  </div>

  <!-- Results Info -->
  <div class="results-info">
    <div class="results-count">
      <span id="resultsText">Mostrando 1-10 de 150 empleados</span>
    </div>
    
    <div class="results-actions">
      <div class="page-size-selector">
        <label for="pageSize">Mostrar:</label>
        <select id="pageSize" class="page-size-select">
          <option value="10">10</option>
          <option value="25" selected>25</option>
          <option value="50">50</option>
          <option value="100">100</option>
        </select>
        <span>por página</span>
      </div>
      
      <div class="bulk-actions" id="bulkActions" style="display: none;">
        <span class="selected-count" id="selectedCount">2 seleccionados</span>
        <button class="btn btn-sm btn-secondary" id="bulkEdit">Editar</button>
        <button class="btn btn-sm btn-danger" id="bulkDelete">Eliminar</button>
      </div>
    </div>
  </div>

  <!-- Data Table -->
  <div class="table-container">
    <div class="table-wrapper">
      <table class="data-table" id="dataTable">
        <thead>
          <tr>
            <th class="select-column">
              <input type="checkbox" id="selectAll" aria-label="Seleccionar todas las filas">
            </th>
            <th class="sortable" data-column="name" data-type="string">
              <div class="th-content">
                <span>Nombre</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="email" data-type="string">
              <div class="th-content">
                <span>Email</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="department" data-type="string">
              <div class="th-content">
                <span>Departamento</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="position" data-type="string">
              <div class="th-content">
                <span>Posición</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="location" data-type="string">
              <div class="th-content">
                <span>Ubicación</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="hireDate" data-type="date">
              <div class="th-content">
                <span>Fecha de Contratación</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="sortable" data-column="status" data-type="string">
              <div class="th-content">
                <span>Estado</span>
                <div class="sort-indicators">
                  <svg class="sort-icon sort-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="18,15 12,9 6,15"></polyline>
                  </svg>
                  <svg class="sort-icon sort-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <polyline points="6,9 12,15 18,9"></polyline>
                  </svg>
                </div>
              </div>
            </th>
            <th class="actions-column">Acciones</th>
          </tr>
        </thead>
        <tbody id="tableBody">
          <!-- Data rows will be populated by JavaScript -->
        </tbody>
      </table>
    </div>
    
    <!-- Loading State -->
    <div class="loading-state" id="loadingState" style="display: none;">
      <div class="loading-spinner"></div>
      <p>Cargando datos...</p>
    </div>
    
    <!-- Empty State -->
    <div class="empty-state" id="emptyState" style="display: none;">
      <svg class="empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
        <circle cx="11" cy="11" r="8"></circle>
        <path d="m21 21-4.35-4.35"></path>
      </svg>
      <h3>No se encontraron empleados</h3>
      <p>Intenta ajustar tus criterios de búsqueda o filtros</p>
      <button class="btn btn-primary" onclick="clearAllFilters()">Limpiar Todos los Filtros</button>
    </div>
  </div>

  <!-- Pagination -->
  <div class="pagination-container">
    <div class="pagination-info">
      <span id="paginationInfo">Mostrando 1 a 25 de 150 entradas</span>
    </div>
    
    <nav class="pagination" aria-label="Paginación de tabla de datos">
      <button class="pagination-btn" id="firstPage" aria-label="Primera página">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <polyline points="11,17 6,12 11,7"></polyline>
          <polyline points="18,17 13,12 18,7"></polyline>
        </svg>
      </button>
      <button class="pagination-btn" id="prevPage" aria-label="Página anterior">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <polyline points="15,18 9,12 15,6"></polyline>
        </svg>
      </button>
      
      <div class="pagination-numbers" id="paginationNumbers">
        <!-- Page numbers will be populated by JavaScript -->
      </div>
      
      <button class="pagination-btn" id="nextPage" aria-label="Página siguiente">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <polyline points="9,18 15,12 9,6"></polyline>
        </svg>
      </button>
      <button class="pagination-btn" id="lastPage" aria-label="Última página">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <polyline points="13,17 18,12 13,7"></polyline>
          <polyline points="6,17 11,12 6,7"></polyline>
        </svg>
      </button>
    </nav>
  </div>

  <!-- Column Toggle Modal -->
  <div class="modal" id="columnModal">
    <div class="modal-content">
      <div class="modal-header">
        <h3>Gestionar Columnas</h3>
        <button class="modal-close" id="closeColumnModal">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
      <div class="modal-body">
        <p>Selecciona qué columnas mostrar en la tabla:</p>
        <div class="column-toggles" id="columnToggles">
          <!-- Column toggles will be populated by JavaScript -->
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-secondary" id="resetColumns">Restablecer por Defecto</button>
        <button class="btn btn-primary" id="applyColumns">Aplicar Cambios</button>
      </div>
    </div>
  </div>

  <!-- Export Modal -->
  <div class="modal" id="exportModal">
    <div class="modal-content">
      <div class="modal-header">
        <h3>Exportar Datos</h3>
        <button class="modal-close" id="closeExportModal">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
      <div class="modal-body">
        <p>Elige el formato de exportación y opciones:</p>
        <div class="export-options">
          <div class="export-format">
            <label>Formato de Exportación:</label>
            <div class="radio-group">
              <label class="radio-option">
                <input type="radio" name="exportFormat" value="csv" checked>
                <span>CSV</span>
              </label>
              <label class="radio-option">
                <input type="radio" name="exportFormat" value="json">
                <span>JSON</span>
              </label>
              <label class="radio-option">
                <input type="radio" name="exportFormat" value="print">
                <span>Imprimir</span>
              </label>
            </div>
          </div>
          
          <div class="export-scope">
            <label>Alcance de Exportación:</label>
            <div class="radio-group">
              <label class="radio-option">
                <input type="radio" name="exportScope" value="current" checked>
                <span>Página Actual</span>
              </label>
              <label class="radio-option">
                <input type="radio" name="exportScope" value="filtered">
                <span>Todos los Resultados Filtrados</span>
              </label>
              <label class="radio-option">
                <input type="radio" name="exportScope" value="all">
                <span>Todos los Datos</span>
              </label>
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-secondary" id="cancelExport">Cancelar</button>
        <button class="btn btn-primary" id="confirmExport">Exportar</button>
      </div>
    </div>
  </div>
</div>

Características del Fragmento

Diseño Responsivo: Sí
Soporte para Modo Oscuro: No
Categoría: feature-sections
Nivel de Dificultad: Avanzado