modern-table-js
Version:
Modern, lightweight, vanilla JavaScript table library with zero dependencies. 67% faster than DataTables with mobile-first responsive design.
200 lines (185 loc) • 6.6 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test: Search Functionality</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/modern-table.css" rel="stylesheet">
<link href="/responsive.css" rel="stylesheet">
<link href="/themes.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
<h2>🔍 Test: Search Functionality</h2>
<p class="text-muted">Testing dual endpoint search with DummyJSON API</p>
<div class="alert alert-info">
<h6>🎯 Test Cases:</h6>
<ul class="mb-0">
<li><strong>Search "james"</strong> → Should show users with name James</li>
<li><strong>Search "emily"</strong> → Should show users with name Emily</li>
<li><strong>Search "@gmail"</strong> → Should show users with Gmail addresses</li>
<li><strong>Clear search</strong> → Should return to all users with pagination</li>
</ul>
</div>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Users Table with Search</h5>
<div class="badge bg-primary" id="endpoint-indicator">Regular Endpoint</div>
</div>
<div class="card-body">
<table id="search-table" class="table table-striped"></table>
</div>
</div>
<div class="mt-4">
<h5>🔗 Current Request URL:</h5>
<div class="bg-light p-3 rounded">
<code id="current-url">Loading...</code>
</div>
</div>
<div class="mt-3">
<h5>📊 Response Info:</h5>
<div class="row">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="card-title">Total Records</h6>
<h4 class="text-primary" id="total-records">-</h4>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="card-title">Filtered Records</h6>
<h4 class="text-success" id="filtered-records">-</h4>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="card-title">Current Page</h6>
<h4 class="text-info" id="current-page">-</h4>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="card-title">Endpoint Type</h6>
<h4 class="text-warning" id="endpoint-type">-</h4>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="module">
import { ModernTable } from "/core/ModernTable.js";
let currentUrl = '';
let isSearching = false;
const table = new ModernTable("#search-table", {
api: {
url: "https://dummyjson.com/users",
method: "GET",
beforeRequest: async (config) => {
const params = config.data || {};
// Use different endpoint for search vs pagination
if (params.search?.value) {
// Search endpoint
const query = new URLSearchParams({
q: params.search.value,
limit: params.length || 10,
skip: params.start || 0
});
config.url = `https://dummyjson.com/users/search?${query}`;
isSearching = true;
updateEndpointIndicator('Search Endpoint', 'bg-warning');
} else {
// Regular pagination endpoint
const query = new URLSearchParams({
limit: params.length || 10,
skip: params.start || 0
});
config.url = `https://dummyjson.com/users?${query}`;
isSearching = false;
updateEndpointIndicator('Regular Endpoint', 'bg-primary');
}
currentUrl = config.url;
updateUrlDisplay();
console.log("🔍 Request URL:", config.url);
return config;
},
dataSrc: function(json) {
// Update stats
updateStats(json, table.currentPage);
console.log("📥 Response data:", {
total: json.total,
users: json.users?.length,
isSearch: isSearching
});
return {
draw: json.draw || 1,
recordsTotal: json.total,
recordsFiltered: json.total,
data: json.users
};
}
},
columns: [
{ data: "id", title: "ID", width: "60px" },
{
data: "firstName",
title: "First Name",
render: function(data, type, row) {
return `<strong>${data}</strong>`;
}
},
{
data: "lastName",
title: "Last Name",
render: function(data, type, row) {
return `<strong>${data}</strong>`;
}
},
{
data: "email",
title: "Email",
render: function(data, type, row) {
return `<a href="mailto:${data}">${data}</a>`;
}
},
{ data: "phone", title: "Phone" }
],
serverSide: true,
pageLength: 10,
paging: true,
searching: true,
ordering: true,
responsive: true,
language: {
search: "🔍 Search users:",
info: "Showing _START_ to _END_ of _TOTAL_ users",
infoFiltered: "(filtered from _MAX_ total users)"
}
});
function updateUrlDisplay() {
document.getElementById('current-url').textContent = currentUrl;
}
function updateEndpointIndicator(text, className) {
const indicator = document.getElementById('endpoint-indicator');
indicator.textContent = text;
indicator.className = `badge ${className}`;
}
function updateStats(json, currentPage) {
document.getElementById('total-records').textContent = json.total || 0;
document.getElementById('filtered-records').textContent = json.users?.length || 0;
document.getElementById('current-page').textContent = currentPage || 1;
document.getElementById('endpoint-type').textContent = isSearching ? 'Search' : 'Pagination';
}
// Initial load
updateUrlDisplay();
</script>
</body>
</html>