JSFiddle - React, Tailwind, and code Playground
by graphettion
HTML
<div class="container">
<h1>Dynamic Data Table</h1>
<div class="controls">
<div class="search-container">
<input type="text" id="searchInput" placeholder="Search..." />
<span class="search-icon">🔍</span>
</div>
<div class="filter-container">
<select id="statusFilter">
<option value="">All Statuses</option>
<option value="active">Active</option>
<option value="pending">Pending</option>
<option value="inactive">Inactive</option>
</select>
<select id="categoryFilter">
<option value="">All Categories</option>
<!-- Will be populated from API data -->
</select>
<button id="resetButton" class="reset">Reset Filters</button>
</div>
</div>
<div id="tableContainer" class="table-container">
<div class="loading-container">
<div class="spinner"></div>
</div>
</div>
<div class="pagination">
<div class="page-info">
Showing <span id="startEntry">0</span> to
<span id="endEntry">0</span> of
<span id="totalEntries">0</span> entries
</div>
<div class="page-controls">
<button id="prevButton" disabled>Prev</button>
<button id="nextButton" disabled>Next</button>
</div>
</div>
</div>
</body>
</html>
CSS
:root {
--primary-color: #3498db;
--primary-hover: #2980b9;
--secondary-color: #e9e9e9;
--text-color: #333;
--border-color: #ddd;
--success-color: #2ecc71;
--warning-color: #f39c12;
--danger-color: #e74c3c;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #f8f9fa;
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 20px;
margin-bottom: 20px;
}
h1 {
color: var(--primary-color);
margin-bottom: 20px;
font-weight: 600;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 10px;
}
.search-container {
position: relative;
flex: 1;
min-width: 200px;
max-width: 400px;
}
.search-container input {
width: 100%;
padding: 10px 15px;
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 16px;
transition: border-color 0.2s;
}
.search-container input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.25);
}
.search-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #999;
}
.filter-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
select {
padding: 10px;
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: white;
min-width: 120px;
font-size: 16px;
}
select:focus {
outline: none;
border-color: var(--primary-color);
}
button {
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.2s;
}
button:hover {
background-color: var(--primary-hover);
}
button.reset {
...
JavaScript
// Configuration
const config = {
itemsPerPage: 5,
mockApiDelay: 500, // Simulates network latency
mockErrorRate: 0, // Set between 0-1 to simulate API errors (e.g., 0.2 for 20%)
}
// State management
const state = {
data: [],
filteredData: [],
currentPage: 0,
sortColumn: "id",
sortDirection: "asc",
searchTerm: "",
statusFilter: "",
categoryFilter: "",
loading: true,
error: null,
}
// DOM Elements
const elements = {
tableContainer: document.getElementById("tableContainer"),
searchInput: document.getElementById("searchInput"),
statusFilter: document.getElementById("statusFilter"),
categoryFilter: document.getElementById("categoryFilter"),
resetButton: document.getElementById("resetButton"),
prevButton: document.getElementById("prevButton"),
nextButton: document.getElementById("nextButton"),
startEntry: document.getElementById("startEntry"),
endEntry: document.getElementById("endEntry"),
totalEntries: document.getElementById("totalEntries"),
}
// Mock data for the API
const mockData = [
{
id: 1,
name: "Wireless Headphones",
category: "Electronics",
price: 99.99,
status: "active",
createdAt: "2025-01-05T08:12:34",
},
{
id: 2,
name: "Smart Watch",
category: "Electronics",
price: 159.99,
status: "active",
createdAt: "2025-01-10T11:23:45",
},
{
id: 3,
name: "Ergonomic Desk Chair",
category: "Furniture",
price: 249.95,
status: "inactive",
createdAt: "2025-01-12T09:34:56",
},
{
id: 4,
name: "LED Desk Lamp",
category: "Home",
price: 39.99,
status: "active",
createdAt: "2025-01-15T14:45:23",
},
{
id: 5,
name: "Mechanical Keyboard",
category: "Electronics",
price: 129.99,
status: "pending",
createdAt: "2025-01-18T16:56:12",
},
{
id: 6,
name: "Coffee Maker",
category: "Kitchen",
price: 79.99,
status: "active",
createdAt: "2025-01-20T10:23:45",
},
{
id: 7,
...