<!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Table CRUD with Sorting, Pagination, Search, and Export</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
th, td {
border: 1px solid #ccc;
padding: 10px;
text-align: left;
}
th {
cursor: pointer;
background-color: #f4f4f4;
}
.pagination {
display: flex;
justify-content: center;
gap: 5px;
}
.pagination button {
padding: 5px 10px;
cursor: pointer;
}
.hidden {
display: none;
}
.context-menu {
position: absolute;
display: none;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.context-menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.context-menu li {
padding: 8px 12px;
cursor: pointer;
}
.context-menu li:hover {
background-color: #f4f4f4;
}
</style>
</head>
<body>
<h1>Table with CRUD, Sorting, Pagination, Context Menu, Search, and Export</h1>
<input type="text" id="search" placeholder="Search...">
<button onclick="exportToExcel()">Export to Excel</button>
<table id="dataTable">
<thead>
<tr>
<th onclick="sortTable(0)">ID</th>
<th onclick="sortTable(1)">Name</th>
<th onclick="sortTable(2)">Age</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- Dynamic rows will be added here -->
</tbody>
</table>
<div class="pagination" id="pagination"></div>
<div class="context-menu" id="contextMenu">
<ul>
<li onclick="editRow()">Edit</li>
<li onclick="deleteRow()">Delete</li>
</ul>
</div>
<script>
const tableData = [
{ id: 1, name: "John Doe", age: 25 },
{ id: 2, name: "Jane Smith", age: 30 },
{ id: 3, name: "Alice Johnson", age: 28 },
{ id: 4, name: "Bob Brown", age: 35 },
{ id: 5, name: "Charlie Davis", age: 22 }
];
let currentPage = 1;
const rowsPerPage = 3;
let currentContextRow = null;
const tableBody = document.querySelector("#dataTable tbody");
const pagination = document.getElementById("pagination");
const contextMenu = document.getElementById("contextMenu");
function renderTable() {
tableBody.innerHTML = "";
const start = (currentPage - 1) * rowsPerPage;
const end = start + rowsPerPage;
const filteredData = tableData.slice(start, end);
filteredData.forEach(row => {
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${row.id}</td>
<td>${row.name}</td>
<td>${row.age}</td>
<td>
<button onclick="editRow(${row.id})">Edit</button>
<button onclick="deleteRow(${row.id})">Delete</button>
</td>
`;
tr.addEventListener("contextmenu", (e) => {
e.preventDefault();
currentContextRow = row.id;
showContextMenu(e.pageX, e.pageY);
});
tableBody.appendChild(tr);
});
renderPagination();
}
function renderPagination() {
pagination.innerHTML = "";
const totalPages = Math.ceil(tableData.length / rowsPerPage);
for (let i = 1; i <= totalPages; i++) {
const button = document.createElement("button");
button.textContent = i;
button.className = i === currentPage ? "active" : "";
button.onclick = () => {
currentPage = i;
renderTable();
};
pagination.appendChild(button);
}
}
function sortTable(columnIndex) {
tableData.sort((a, b) => {
const valA = Object.values(a)[columnIndex];
const valB = Object.values(b)[columnIndex];
return valA > valB ? 1 : -1;
});
renderTable();
}
function searchTable() {
const searchValue =
document.getElementById("search").value.toLowerCase();
tableBody.innerHTML = "";
tableData.filter(row =>
Object.values(row).some(value =>
value.toString().toLowerCase().includes(searchValue)
)
).forEach(row => {
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${row.id}</td>
<td>${row.name}</td>
<td>${row.age}</td>
<td>
<button onclick="editRow(${row.id})">Edit</button>
<button onclick="deleteRow(${row.id})">Delete</button>
</td>
`;
tableBody.appendChild(tr);
});
}
function editRow(id) {
const row = tableData.find(r => r.id === id);
const newName = prompt("Enter new name:", row.name);
const newAge = prompt("Enter new age:", row.age);
if (newName && newAge) {
row.name = newName;
row.age = parseInt(newAge, 10);
renderTable();
}
}
function deleteRow(id) {
const index = tableData.findIndex(r => r.id === id);
if (index !== -1) {
tableData.splice(index, 1);
renderTable();
}
}
function exportToExcel() {
const csv = ["ID,Name,Age"];
tableData.forEach(row => {
csv.push(`${row.id},${row.name},${row.age}`);
});
const blob = new Blob([csv.join("\n")], { type: "text/csv" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "table_data.csv";
a.click();
URL.revokeObjectURL(url);
}
function showContextMenu(x, y) {
contextMenu.style.left = `${x}px`;
contextMenu.style.top = `${y}px`;
contextMenu.style.display = "block";
}
function hideContextMenu() {
contextMenu.style.display = "none";
}
document.addEventListener("click", hideContextMenu);
document.getElementById("search").addEventListener("input", searchTable);
renderTable();
</script>
</body>
</html>