dynamically loaded data while changing input value . after selecting dropdown value not able to select the next dropdown … and i want the symbol down icon bold color
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Handsontable with Dynamic Dropdown</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable@8.4.0/dist/handsontable.full.min.css">
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
font-family: Arial, sans-serif;
background-color: #f1f1f1;
}
.handsontable-container {
width: 100vw;
height: calc(100vh - 50px);
box-sizing: border-box;
}
.search-container, .save-container {
padding: 10px;
background-color: #ffffff;
}
.htDropdown {
white-space: nowrap; /* Prevent text wrapping */
overflow: visible; /* Ensure dropdown content is fully visible */
min-width: 150px; /* Set a minimum width */
box-sizing: border-box; /* Include padding and border in the element's total width */
}
</style>
<div class="search-container">
<input type="text" id="search-input" class="form-control" placeholder="Search...">
</div>
<div class="save-container">
<button id="save-button" class="btn btn-primary" disabled>Save</button>
</div>
<div class="container">
<button id="export-button" class="btn btn-primary mb-3">Export to Excel</button>
</div>
<div id="handsontable-container" class="handsontable-container"></div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/handsontable@8.4.0/dist/handsontable.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xlsx/dist/xlsx.full.min.js"></script>
<script>
const container = document.getElementById('handsontable-container');
const searchField = document.getElementById('search-input');
const saveButton = document.getElementById('save-button');
let hot;
let originalData = [];
let changedRows = {};
function initHandsontable(headers, data) {
originalData = JSON.parse(JSON.stringify(data));
hot = new Handsontable(container, {
data: data,
colHeaders: headers,
rowHeaders: true,
minCols: 50,
minRows: 100,
stretchH: 'all',
autoWrapRow: true,
width: container.clientWidth,
height: container.clientHeight,
contextMenu: true,
manualColumnResize: true,
manualRowResize: true,
licenseKey: 'non-commercial-and-evaluation',
colWidths: 100,
rowHeights: 30,
afterChange: function (changes, source) {
if (source === 'loadData') return;
detectChanges(changes);
changes.forEach(([row, col, oldValue, newValue]) => {
if (col === 1) { // Assuming column index 1 is where the dropdown is
console.log(row)
handleDropdownSelection(row, newValue);
}
if(col===4 || col===5 || col===6 || col===7)
{
var nos=this.getDataAtCell(row,4).split('X');
var len=this.getDataAtCell(row,5);
if(len==null){len=1;}
var bre=this.getDataAtCell(row,6);
if(bre==null){bre=1;}
var hei=this.getDataAtCell(row,7);
if(hei==null){hei=1;}
var qu=parseFloat(len)*parseFloat(bre)*parseFloat(hei) * parseFloat(nos[0])* parseFloat(nos[1]);
console.log(parseFloat(qu))
this.setDataAtCell(row,8,parseFloat(qu))
console.log(newValue)
}
});
},
cells: function (row, col) {
const cellProperties = {};
if (col === 1) { // Assuming column index 1 is where we need to fetch dropdown options
cellProperties.type = 'dropdown';
cellProperties.source = function(query, process) {
fetchDropdownOptions(query).then(data => {
const maxOptionWidth = calculateMaxOptionWidth(data);
setDropdownWidth(maxOptionWidth);
process(data);
adjustDropdowns();
}).catch(error => {
console.error('Error fetching dropdown options:', error);
process([]);
});
};
}
return cellProperties;
},
contextMenu: {
items: {
"pasteValues": {
name: 'Paste Column Values',
callback: function() {
var selected = hot.getSelected(); // Get the selected range
if (selected && selected.length > 0) {
var col = selected[0][1]; // Get the column index
var values = [];
var lastRow = hot.countRows() - 1;
// Get values from the selected column
for (var i = 0; i < lastRow; i++) {
values.push(hot.getDataAtCell(i, col));
}
// Insert values into the next row
for (var j = 0; j < values.length; j++) {
hot.setDataAtCell(lastRow + 1, col, values[j]);
}
} else {
alert('Please select a column to copy values from.');
}
}
}
}
}
});
function handleDropdownSelection(row, selectedValue) {
// Get headers
const headers = hot.getColHeader();
var myArray=[];
myArray = selectedValue.split(",");
console.log(myArray)
//headers.forEach((header, col) => {
//console.log(header)
// For example, update cells in columns with a header containing 'Update'
//if (header.includes('item_code')) {
hot.setDataAtCell(row, 2, myArray[1]);
//}
//if (header.includes('project_name')) {
//hot.setDataAtCell(row, 1, myArray[0]);
//}
//});
}
function setDropdownWidth(width) {
requestAnimationFrame(() => {
const dropdowns = document.querySelectorAll('.handsontableEditor'); // Verify this selector in your browser
dropdowns.forEach(dropdown => {
dropdown.style.width = `${width + 20}px`; // Adding padding
dropdown.style.overflow = 'visible'; // Ensure dropdown text is not truncated
});
const dropdowns1 = document.querySelectorAll('.handsontable.listbox .ht_master table'); // Verify this selector in your browser
dropdowns1.forEach(dropdown => {
dropdown.style.width = `${width + 20}px`; // Adding padding
dropdown.style.overflow = 'visible'; // Ensure dropdown text is not truncated
});
});
}
function adjustDropdowns() {
const dropdowns = document.querySelectorAll('.handsontableEditor'); // Verify this selector
dropdowns.forEach(dropdown => {
const options = dropdown.querySelectorAll('.handsontable.listbox .ht_master table tr td');
let maxWidth = 0;
options.forEach(option => {
const width = option.clientWidth;
if (width > maxWidth) {
maxWidth = width;
}
});
setDropdownWidth(maxWidth);
});
}
hot.addHook(‘afterRender’, function() {
adjustDropdowns(); // Adjust dropdown width after rendering
});
hot.addHook(‘afterChange’, function(changes, source) {
if (source === 'loadData') return;
adjustDropdowns(); // Adjust dropdown width after data changes
});
window.addEventListener('resize', function () {
hot.updateSettings({
width: container.clientWidth,
height: container.clientHeight
});
});
}
function calculateMaxOptionWidth(options) {
let maxWidth = 0;
const dummyDiv = document.createElement('div');
dummyDiv.style.visibility = 'hidden';
dummyDiv.style.position = 'absolute';
dummyDiv.style.whiteSpace = 'nowrap'; // Prevent text wrapping
dummyDiv.style.padding = '5px'; // Add padding to match dropdown
document.body.appendChild(dummyDiv);
options.forEach(option => {
dummyDiv.textContent = option;
const width = dummyDiv.offsetWidth;
if (width > maxWidth) {
maxWidth = width;
}
});
document.body.removeChild(dummyDiv);
return maxWidth;
}
function setDropdownWidth(width) {
setTimeout(() => {
const dropdowns = document.querySelectorAll('.htDropdown');
dropdowns.forEach(dropdown => {
dropdown.style.width = `${width + 20}px`; // Adding padding
dropdown.style.overflow = 'visible'; // Ensure dropdown text is not truncated
});
}, 0); // Delay to ensure dropdown is rendered
}
function loadData() {
$.ajax({
url: 'fetch_data.php',
method: 'GET',
dataType: 'json',
success: function(response) {
const headers = response.headers;
const data = response.data;
initHandsontable(headers, data);
},
error: function(xhr, status, error) {
console.error('Error fetching data:', status, error);
}
});
}
function detectChanges(changes) {
changes.forEach(([row, col, oldValue, newValue]) => {
if (!changedRows[row]) {
changedRows[row] = hot.getDataAtRowProp(row) || hot.getDataAtRow(row);
}
changedRows[row][col] = newValue;
if (col === 1) { // Assuming column index 1 is where we need to fetch dropdown options
updateDropdownsForRow(row, newValue);
}
});
saveButton.disabled = Object.keys(changedRows).length === 0;
}
function saveDataToServer() {
$.ajax({
url: 'save_data.php',
method: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({ changedRows: changedRows }),
success: function(response) {
changedRows = {};
saveButton.disabled = true;
},
error: function(xhr, status, error) {
console.error('Error saving data:', status, error);
}
});
}
function updateDropdownsForRow(row, value) {
fetchDropdownOptions(value).then(data => {
const maxOptionWidth = calculateMaxOptionWidth(data);
setDropdownWidth(maxOptionWidth);
hot.updateSettings({
cells: function (r, c) {
if (r === row && c === 1) { // Update dropdown for the specific row and column
return {
type: 'dropdown',
source: data
};
}
return {};
}
});
hot.render();
}).catch(error => {
console.error('Error updating dropdown options:', error);
});
}
function fetchDropdownOptions(query) {
return new Promise((resolve, reject) => {
$.ajax({
url: 'fetch_drop_down.php',
method: 'GET',
data: { query: query },
success: function(response) {
resolve(response);
},
error: function(xhr, status, error) {
reject([]);
}
});
});
}
loadData();
searchField.addEventListener('keyup', function () {
const search = hot.getPlugin('search');
search.query(searchField.value);
hot.render();
});
saveButton.addEventListener('click', function () {
saveDataToServer();
});
const exportButton = document.getElementById('export-button');
//const exportPlugin = hot.getPlugin('exportFile');
function exportToExcel() {
const headers = hot.getColHeader(); // Get column headers
const data = hot.getData(); // Get table data
// Combine headers and data
const worksheetData = [headers].concat(data); // Add headers as the first row
const ws = XLSX.utils.aoa_to_sheet(worksheetData); // Convert to SheetJS format
const wb = XLSX.utils.book_new(); // Create a new workbook
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); // Append the sheet to the workbook
XLSX.writeFile(wb, 'handsontable_data.xlsx'); // Write the workbook to a file
}
exportButton.addEventListener('click', function () {
exportToExcel();
});