I am using Grid.js to display a table with multiple columns. I want to provide the user with the ability to toggle the visibility of specific columns in the grid. For example, I have a dropdown with checkboxes that allow the user to show or hide individual columns based on their preferences but the columns don't save when the page is refreshed or if I use grid.js built in search it sets the grid back to default and only effects the column that the search was applied too.
Here's a simplified version of my current code:
function updateTableWithDBData() {
fetch("/getTransactions")
//Code for grabbing data to populate columns
});
// Dropdown for showing/hiding columns
const dropdown = document.createElement('div');
dropdown.classList.add('dropdown');
const dropdownButton = document.createElement('button');
dropdownButton.classList.add('dropbtn');
dropdownButton.textContent = 'Toggle Columns';
const dropdownContent = document.createElement('div');
dropdownContent.classList.add('dropdown-content');
const dropdownList = document.createElement('ul');
for (const column of columns) {
const listItem = document.createElement('li');
const checkboxLabel = document.createElement('label');
checkboxLabel.classList.add('checkbox-label');
checkboxLabel.textContent = column;
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = true;
checkbox.addEventListener('change', function () {
const columnIndex = columns.indexOf(column);
const headerCell = document.querySelector('#grid th:nth-child(' + (columnIndex + 1) + ')');
const cells = document.querySelectorAll('#grid td:nth-child(' + (columnIndex + 1) + '), #grid th:nth-child(' + (columnIndex + 1) + ')');
if (checkbox.checked) {
headerCell.style.display = '';
for (const cell of cells) {
cell.style.display = '';
}
} else {
headerCell.style.display = 'none';
for (const cell of cells) {
cell.style.display = 'none';
}
}
});
checkboxLabel.appendChild(checkbox);
listItem.appendChild(checkboxLabel);
dropdownList.appendChild(listItem);
}
dropdownContent.appendChild(dropdownList);
dropdown.appendChild(dropdownButton);
dropdown.appendChild(dropdownContent);
// Hide all headers and columns initially
const headerCells = document.querySelectorAll('#grid th');
const dataCells = document.querySelectorAll('#grid td');
for (const headerCell of headerCells) {
headerCell.style.display = 'none';
}
for (const cell of dataCells) {
cell.style.display = 'none';
}
document.getElementById('grid-dropdown').appendChild(dropdown);
const grid = new gridjs.Grid({
columns: columns.map((column) => ({ name: column, id: column, formatter: 'html' })),
data: gridData,
sort: true,
search: true,
storage: 'local'
});
// Function to update the grid with the current state of the toggle boxes
const updateGridWithCheckboxState = () => {
const headerCells = document.querySelectorAll('#grid th');
const dataCells = document.querySelectorAll('#grid td');
for (const [index, column] of columns.entries()) {
const checkbox = document.querySelector(`#grid-dropdown input:nth-of-type(${index + 1})`);
const headerCell = headerCells[index];
const cells = document.querySelectorAll(`#grid td:nth-child(${index + 1}), #grid th:nth-child(${index + 1})`);
if (checkbox && headerCell && cells.length > 0) {
if (checkbox.checked) {
headerCell.style.display = '';
for (const cell of cells) {
cell.style.display = '';
}
} else {
headerCell.style.display = 'none';
for (const cell of cells) {
cell.style.display = 'none';
}
}
}
}
};
// Function to save the state of the toggle boxes to local storage
const saveCheckboxStateToLocalStorage = () => {
const checkboxStates = {};
const checkboxes = document.querySelectorAll('#grid-dropdown input[type="checkbox"]');
for (const [index, checkbox] of checkboxes.entries()) {
const column = columns[index];
checkboxStates[column] = checkbox.checked;
}
localStorage.setItem('checkboxStates', JSON.stringify(checkboxStates));
};
// Function to load the state of the toggle boxes from local storage
const loadCheckboxStateFromLocalStorage = () => {
const checkboxStates = JSON.parse(localStorage.getItem('checkboxStates'));
if (checkboxStates) {
const checkboxes = document.querySelectorAll('#grid-dropdown input[type="checkbox"]');
for (const [index, checkbox] of checkboxes.entries()) {
const column = columns[index];
if (checkboxStates[column] !== undefined) {
checkbox.checked = checkboxStates[column];
}
}
}
};
// Attach event listener to checkboxes to update grid and save state to local storage
const checkboxes = document.querySelectorAll('#grid-dropdown input[type="checkbox"]');
checkboxes.forEach((checkbox) => {
checkbox.addEventListener('change', () => {
updateGridWithCheckboxState();
saveCheckboxStateToLocalStorage();
});
});
// Load the checkbox state from local storage and update the grid
loadCheckboxStateFromLocalStorage();
updateGridWithCheckboxState();
grid.render(gridContainer);
})
.catch((error) => {
console.error('Error:', error);
});
}
document.addEventListener('DOMContentLoaded', () => {
updateTableWithDBData();
});
This is the normal state of my grid This is my grid with 2 columns hidden This is what my grid looks like when I search This is what my grid looks like when I cancel the search(Notice the columns have been reset) This is what my grid looks like after I refresh the page (notice the columns are shown even though the check boxes are unticked.
I have already tried implementing the column toggling functionality using the Grid.js API, but I seem to be running into issues. The columns are not toggling as expected, and the grid does not remember the user's choices when they toggle columns.
I am seeking guidance on how to properly implement the column toggling functionality using Grid.js. I want the grid to remember the user's choices when they toggle columns and display/hide the columns accordingly and not reset the toggling of the grid if I use the search.
Can someone please provide a step-by-step explanation or code example on how to achieve column toggling in Grid.js along with keeping the user's choices synchronized with the grid state?