react-table-plugins icon indicating copy to clipboard operation
react-table-plugins copied to clipboard

useCellRangeSelection fails with virtualization

Open danvln opened this issue 4 years ago • 4 comments

Hey,

First of all, this is a great hook! Thanks for providing it - all the appreciation for your work.

I tried the useCellRangeSelection with virtualization, I have enabled in my POC project both: react-window and react-virtual, but for both of them the hook is failing.

Error details:

Error: React Table: startCellId and endCellId has to be valid cell Id

Code path:

// Returns all cells between Range ( between startcell and endcell Ids) const getCellsBetweenId = React.useCallback( (startCell, endCell) => { if (!cellsById[startCell] || !cellsById[endCell]) { console.info({ startCell, endCell }) throw new Error( React Table: startCellId and endCellId has to be valid cell Id ) }

I was expecting the cells to be used from the object that's still in memory and not from the rendering objects that are dropped. But since I am new to these hooks I might miss something.

Thanks again.

danvln avatar Oct 28 '20 01:10 danvln

Glad, anyone asked about it, so one of the reason for this can be cell ids are assigned in prepareRow which when virtualizing can skip for some rows but in getCellsBetweenId they are required. To fix this, cell id dependency has to be removed from getCellsBetweenId with some other logic, i will have a look at this..

gargroh avatar Oct 28 '20 10:10 gargroh

Thank you, Rohit. I will keep following if there is any update on this; and I can take a deeper look into the code and we can discuss solutions over the weekend. Glad to see your quick response. Also, sorry for opening a duplicate issue. GitHub did a timeout on first, but it looks that it opened it.

danvln avatar Oct 28 '20 17:10 danvln

Hello, sorry to reopen the topic. I'm trying to use the plugin as well and I'm having trouble. The problem comes from the cellsById instance which when initializing the table is empty. Have you encountered this problem? Can you help me ?

Tozzy-dev avatar May 03 '22 08:05 Tozzy-dev

Just if this is still on the table. If you need useRangeSelection to work with virtualization, here is the code.

Just replace getCellsBetweenId with this function. Kudos to @gargroh for prompt on removing cellsById dependency

const getCellsBetweenId = React.useCallback(
   (startCell: string, endCell: string) => {
     const updatedRows = rows.map((el, idx) => ({ ...el, index: idx }));

     const startCellPosition = updatedRows.findIndex((el) => startCell.includes(el.id));
     const endCellPosition = updatedRows.findIndex((el) => endCell.includes(el.id));

     if (startCellPosition === -1 || endCellPosition === -1) {
       throw new Error(`React Table: startCellId and endCellId has to be valid cell Id`);
     }

     const rowsIndex = [startCellPosition, endCellPosition];

     const columnsIndex: number[] = [];
     allColumns.forEach((col, index) => {
       if (startCell.includes(col.id)) {
         columnsIndex.push(index);
       }
     });

     const selectedColumns = [];
     const selectedRows = [];
     for (let i = Math.min(...columnsIndex); i <= Math.max(...columnsIndex); i++) {
       selectedColumns.push(allColumns[i].id);
     }
     for (let i = 0; i <= updatedRows.length - 1; i++) {
       if (updatedRows[i].index >= Math.min(...rowsIndex) && updatedRows[i].index <= Math.max(...rowsIndex)) {
         selectedRows.push(updatedRows[i].id);
       }

       if (updatedRows[i].index === Math.max(...rowsIndex)) break;
     }

     const cellsBetween: { [keys: string]: boolean } = {};

     if (selectedRows.length && selectedColumns.length) {
       for (const item of selectedRows) {
         for (const item1 of selectedColumns) {
           const id = item1 + cellIdSplitBy + item;
           cellsBetween[id] = true;
         }
       }
     }

     return cellsBetween;
   },
   [allColumns, cellIdSplitBy, rows],
 );

vzherebetskyi avatar Apr 04 '24 10:04 vzherebetskyi