BetaStranger12
BetaStranger12

Reputation: 62

Move columns and update state react - Handsontable data grid

I am using the library for React, I have a list (array) of the headers, and on the other side an array of array with the table data.

I reading the documentation I was able to enable the menu, among them I added the option to "Add a column to the left" and "Add a column to the right", but this is done visually and does not update the states of the headers in the react state.

I tried these two ways. The second way, as "Custom dropdown menu configuration", I manually added the column, and used the handsontable method "updateSettings" to update the headers, but it still doesn't work (At times it works and at other times it adds the column elsewhere).

function addToHeader (array, index, side, valor) {
  if (side === "Left") array.splice(index, 0, valor)
  else if (side === "Right") array.splice(index + 1, 0, valor)
  return array
}

In the code:
dropdownMenu: {
      items: {
        col_right: {
          name: 'Move column right',
          callback: (key: any, selection: any, clickEvent: any) => {
            const column = selection[0].end.col
            headers = addToHeader(headers, column, "Right", 'New column')
            console.log('headers', headers) // Returns the array with the correct changes
            hot.updateSettings({ colHeaders: headers })
          }

        },
        col_left: {
          name: 'Move column left',
          callback: (key: any, selection: any, clickEvent: any) => {
            const column = selection[0].end.col
            headers = addToHeader(headers, column, "Left", 'New column')
            console.log('headers', headers) // Returns the array with the correct changes
            hot.updateSettings({ colHeaders: headers })
          }
        },
}

Upvotes: 0

Views: 234

Answers (1)

BetaStranger12
BetaStranger12

Reputation: 62

I managed to complete this as follows:

afterColumnMove: (
  movedColumns: number[],
  finalIndex: number,
  dropIndex: number | undefined,
  movePossible: boolean,
  orderChanged: boolean
) => {
  if (orderChanged) {
    let ht
    if (hotRef.current) ht = hotRef.current.hotInstance
    if (ht) {
      const headers = ht.getColHeader()
      const colMoved = movedColumns[0]
      setHeaders(prevHeaders => headers as string[]) // This way if you update the state
      const newOrderData = moveColumnTable(list, finalIndex, colMoved)
      setList(prevData => newOrderData)
      ht.loadData(list)
    }
  }
}

The key is, and it was what I didn't realize, in addition to the fact that the state of the headers was not being updated, when a column is moved, the table data also has to be updated, and that is where I implemented a function of js to move the information (moveColumnTable)

const moveColumnTable = (tableData: any[], fromIndex: number, toIndex: number) => {
  if (toIndex === fromIndex || toIndex < 0 || fromIndex < 0) {
    // If the start index is equal to the end index or they are invalid values, there are no changes.
    return tableData
  }

  const reorderedTableData = tableData.map(row => {
    const newRow = [...row]
    const movedItem = newRow.splice(toIndex, 1)[0]
    newRow.splice(fromIndex, 0, movedItem)

    return newRow
  })

  return reorderedTableData
}

Important: I implemented this to move a single column

Upvotes: 0

Related Questions