Last active
December 18, 2024 14:07
-
-
Save shijiezhou1/5821f3476bf9d5b7a60c92d3890846e8 to your computer and use it in GitHub Desktop.
Teach you how to make a simple handsontable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Document</title> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" /> | |
<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script> | |
<style> | |
.htCore .yellow { | |
background-color: yellow; | |
/* Change this color as needed */ | |
} | |
.htCore .new-class { | |
background-color: lightblue; | |
/* New class color */ | |
} | |
</style> | |
</head> | |
<body> | |
<div id="example" class="handsontable-container"></div> | |
<button id="changeClassButton">Change Cell Class</button> | |
<button id="downloadCSVButton">Download CSV</button> | |
<div id="changesDisplay"></div> | |
<script> | |
document.addEventListener("DOMContentLoaded", function () { | |
const data = [ | |
["Tesla", "Model S", "2023-01-15", 5, 2, "ORD123", "USA"], | |
["Volvo", "XC90", "2023-02-20", 3, 1, "ORD124", "Sweden"], | |
["Toyota", "Camry", "2023-03-10", 10, 4, "ORD125", "Japan"], | |
["Ford", "Mustang", "2023-04-05", 7, 3, "ORD126", "USA"], | |
["Tesla", "Model 3", "2023-05-12", 8, 2, "ORD127", "USA"], | |
["Volvo", "S60", "2023-06-18", 4, 1, "ORD128", "Sweden"], | |
["Toyota", "Corolla", "2023-07-25", 12, 5, "ORD129", "Japan"], | |
["Ford", "F-150", "2023-08-30", 6, 2, "ORD130", "USA"], | |
]; | |
const colHeaders = [ | |
"Company name", | |
"Name", | |
"Sell date", | |
"In stock", | |
"Qty", | |
"Order ID", | |
"Country" | |
] | |
const columns = [ | |
{ data: 1, type: "text" }, | |
{ data: 2, type: "text" }, | |
{ data: 3, type: "text" }, | |
{ | |
data: 4, | |
type: "text", | |
}, | |
{ data: 5, type: "text" }, | |
{ | |
data: 6, | |
type: "text", | |
}, | |
{ | |
data: 7, | |
type: "text", | |
}, | |
] | |
const container = document.getElementById("example"); | |
const changesLog = []; // Array to store changes | |
const hot = new Handsontable(container, { | |
data: data, | |
colHeaders: colHeaders, | |
columns: columns, | |
licenseKey: "non-commercial-and-evaluation", | |
afterChange: function (changes, source) { | |
if (source === "loadData") { | |
return; // Don't highlight when loading data | |
} | |
console.log(changes); | |
if (changes) { | |
// Check if there are changes | |
changes.forEach(([row, prop, oldValue, newValue]) => { | |
if (oldValue !== newValue) { | |
// Update the comment for the changed cell | |
const cell = hot.getCell(row, prop - 1); // Adjust prop for zero-based index | |
if (cell) { | |
// Retrieve the existing comment | |
const existingComment = hot.getCellMeta(row, prop - 1).comment?.value || ''; | |
const commentText = `- Changed from ${oldValue} ➡️ ${newValue} on ${new Date().toLocaleString()}`; | |
// Append the new change to the existing comment | |
const newComment = existingComment ? `${commentText}\n\n${existingComment}` : commentText; | |
hot.setCellMeta(row, prop - 1, 'comment', { value: newComment, readOnly: true }); // Set new comment as read-only | |
} | |
// Record the change in the changesLog array | |
changesLog.push({ row, prop, oldValue, newValue }); // Store change details | |
renderChangesLog(); // Call function to render changes | |
} | |
}); | |
} | |
hot.render(); | |
}, | |
comments: true, // Keep comments enabled | |
// Add these options to improve user experience | |
manualColumnResize: true, | |
manualRowResize: true, | |
contextMenu: ['copy', 'copy_with_column_headers'], | |
filters: true, | |
// enable the column menu | |
dropdownMenu: true, | |
copyPaste: { | |
copyColumnHeaders: true, | |
copyColumnGroupHeaders: true, | |
copyColumnHeadersOnly: true, | |
} | |
}); | |
function renderChangesLog() { | |
const changesDisplay = document.getElementById("changesDisplay"); | |
changesDisplay.innerHTML = ""; // Clear previous content | |
changesLog.forEach(change => { | |
const changeItem = document.createElement("div"); | |
changeItem.textContent = `Row: ${change.row}, Column: ${change.prop}, Old Value: ${change.oldValue}, New Value: ${change.newValue}`; | |
// changeItem.classList.add("yellow"); // Add the yellow class to each change log item | |
changesDisplay.appendChild(changeItem); | |
}); | |
} | |
document | |
.getElementById("changeClassButton") | |
.addEventListener("click", function () { | |
// Add yellow class to specific change log items based on changesLog | |
console.log(changesLog); | |
changesLog.forEach(change => { | |
const cell = hot.getCell(change.row, change.prop - 1); | |
if (cell) { | |
cell.classList.remove('highlighted'); // Remove previous highlight class if needed | |
cell.classList.add('new-class'); // Add new class to the cell | |
} else { | |
console.log("Cell not found."); | |
} | |
}); | |
// Render the changesLog in the changesDisplay element | |
renderChangesLog(); // Call the function to display changes | |
}); | |
document.getElementById("downloadCSVButton").addEventListener("click", function () { | |
const exportPlugin = hot.getPlugin('exportFile'); | |
// Create a new data array with formatted dates | |
const formattedData = hot.getData().map(row => { | |
return row.map((cell, index) => { | |
// Check if the cell is a date (assuming the date is in the third column, index 2) | |
if (index === 2 && cell instanceof Date) { | |
return cell.toLocaleDateString(); // Format the date as a string | |
} | |
return cell; // Return the cell as is for other columns | |
}); | |
}); | |
exportPlugin.downloadFile('csv', { | |
bom: false, | |
columnDelimiter: ',', | |
columnHeaders: false, | |
exportHiddenColumns: true, | |
exportHiddenRows: true, | |
fileExtension: 'csv', | |
filename: 'Handsontable-CSV-file_[YYYY]-[MM]-[DD]', | |
mimeType: 'text/csv', | |
rowDelimiter: '\r\n', | |
rowHeaders: true, | |
data: formattedData | |
}); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment