How to implement column toggling in Grid.js?

282 Views Asked by At

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?

0

There are 0 best solutions below