javascripthandsontable

handsontable unfreeze a column and return to original position


I'm trying to create a handsontable table where when I freeze the column it goes to the 0th column position, but when you right click to unfreeze I'd like it to go back to its original location.

I've tried using a custom callback unfreezeColumn that takes on the original order of the columns so that if I freeze the column in position index 3 it will go to 0 when frozen and back to 3 when unfrozen, but this custom indexing function is not working

Codepen here: https://codepen.io/MayaRGans/pen/mdNJJwm

$(function() {
  var data = [
    ['Year', 'Maserati', 'Mazda', 'Mercedes', 'Mini', 'Mitsubishi'],
    ['2009', 0, 2941, 4303, 354, 5814],
    ['2010', 5, 2905, 2867, 412, 5284],
    ['2011', 4, 2517, 4822, 552, 6127],
    ['2012', 2, 2422, 5399, 776, 4151]
  ];

  const container = document.getElementById('grid');
  let isUpdatingOrder = false; // Flag to prevent recursion
  const originalOrder = [...Array(data[0].length).keys()]; // Track the original column order
  const hiddenColumnsList = [];
  const expandedCells = {};

  // Initialize Handsontable
  const hot = new Handsontable(container, {
    data: data,
    columns: originalOrder.map((index) => ({
      title: data[0][index],
      minWidth: 150,
      width: 160
    })),
    filters: true,
    dropdownMenu: ['filter_by_value', 'filter_action_bar'],
    height: 900,
    autoWrapRow: true,
    autoWrapCol: true,
    contextMenu: {
      items: {
        "freeze_column": {},
        "unfreeze_column": {
          name: 'Unfreeze column',
          callback: function(key, selection) {
            const colIndex = selection[0].start.col;
            console.log('Unfreezing column index:', colIndex);
            unfreezeColumn(colIndex);
          }
        },
        "hidden_columns_hide": {},
        "hidden_columns_show": {}
      }
    },
    manualColumnFreeze: true,
    readOnly: true,
    editor: false,
    width: '100%',
    colHeaders: true,
    manualColumnResize: true,
    autoColumnSize: true,
    wordWrap: true,
    className: 'jnj-table',
    licenseKey: 'non-commercial-and-evaluation',
    hiddenColumns: {
      columns: hiddenColumnsList,
      indicators: true
    }
  });

  // Function to unfreeze the column
  function unfreezeColumn(colIndex) {
    hot.getPlugin('manualColumnFreeze').unfreezeColumn(colIndex);
    updateColumnOrder();
  }

  // Function to update the column order
  function updateColumnOrder() {
    if (isUpdatingOrder) return; // Prevent recursion
    isUpdatingOrder = true; // Set the flag

    const currentOrder = hot.getSettings().manualColumnMove || [];

    // Restore the columns to the original order only if they're not in the original state
    if (!arraysEqual(currentOrder, originalOrder)) {
      hot.updateSettings({
        manualColumnMove: originalOrder
      });
    }

    hot.render();
    isUpdatingOrder = false; // Reset the flag
  }

  // Helper function to compare two arrays
  function arraysEqual(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    return arr1.every((value, index) => value === arr2[index]);
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://handsontable.com/dist/handsontable.full.js"></script>
<link rel="stylesheet" href=="https://handsontable.com/dist/handsontable.full.css">
<div id="grid" class="handsontable"></div>


Solution

  • I figured it out using the unfreeze and moveColumn methods

    <div id="grid" class="handsontable"></div>
    
    $(function () {
      var data = [
        ['Year', 'Maserati', 'Mazda', 'Mercedes', 'Mini', 'Mitsubishi'],
        ['2009', 0, 2941, 4303, 354, 5814],
        ['2010', 5, 2905, 2867, 412, 5284],
        ['2011', 4, 2517, 4822, 552, 6127],
        ['2012', 2, 2422, 5399, 776, 4151]
      ];
    
      const container = document.getElementById('grid');
      let originalIndex; // To store the original index of the column being frozen
    
      // Initialize Handsontable
      const hot = new Handsontable(container, {
        data: data,
        columns: data[0].map(title => ({ title, minWidth: 150, width: 160 })),
        manualColumnFreeze: true,
        readOnly: true,
        colHeaders: true,
        contextMenu: true,
        height: 900,
        width: '100%',
        licenseKey: 'non-commercial-and-evaluation',
        beforeColumnFreeze: function (currentCol) {
          originalIndex = currentCol; // Store the original index of the column being frozen
        },
        afterColumnUnfreeze: function (currentCol) {
          if (originalIndex !== undefined) {
            // Move the column back to its original position
            hot.getPlugin('manualColumnMove').moveColumn(currentCol, originalIndex);
            hot.render(); // Refresh the table
          }
        }
      });
    });