Due to button validation first value considering null in handsontable

Tags: #<Tag:0x00007efc64eeb6e8>

Hi I have a problem with set Button state in afterValidate function then when we fill first value in handsontable then it consider that value as null and unable to calculate formula or dragToFill functionality.

My code : -
/* eslint-disable consistent-return /
/
eslint-disable array-callback-return */

// Note: R&D work on HandsonTable
const SpreadSheet = (props) => {
const hotRef = useRef(null);
const [sheetIsValid, setSheetIsValid] = useState(false);
const [invalidCells, setInValidCell] = useState(new Set());

const colHeaders = updatedColumnHeaders.map(column => column.displayText.toUpperCase());
const afterValidate = (isValid, value, row, prop) => {
const hot = hotRef.current.hotInstance;
const cellMeta = hot.getCellMeta(row, hot.propToCol(prop));
const data = { col: cellMeta.visualCol, row: cellMeta.visualRow };
const updatedInvalidCells = invalidCells;
if (isValid) {
updatedInvalidCells.forEach((cell) => {
if (cell.col === data.col && cell.row === data.row) {
updatedInvalidCells.delete(cell);
}
});
} else {
updatedInvalidCells.add(data);
}
console.log(‘value–>’, value);
setInValidCell(invalidCells);
setSheetIsValid(invalidCells.size === 0);
};
const highlightInvalidCells = () => {
const hot = hotRef.current.hotInstance;
invalidCells.forEach((data) => {
const cell = hot.getCell(data.row, data.col);
// eslint-disable-next-line no-unused-expressions
!cell.classList.contains(‘htInvalid’) && cell.classList.add(‘htInvalid’);
});
};

const afterChange = (changes) => {
if (changes && changes.length) {
console.log(‘changes–>’, changes);
highlightInvalidCells();
}
};

return (
<>
<Spreadsheet
ref={hotRef}
validateCells
colHeaders={colHeaders}
data={tableDataRender}
rowHeaders
minRows={100}
manualColumnResize
manualRowResize
width=“100%”
height=“400”
stretchH=“all”
filters
fixedColumnsLeft={2}
contextMenu
viewportColumnRenderingOffset={101}
viewportRowRenderingOffset={101}
dropdownMenu={false}
columns={columnHeaders}
formulas={{
engine: HyperFormula,
}}
afterValidate={afterValidate}
afterChange={afterChange}
/>



button disabled={!sheetIsValid} onClick={bulkInsertTableData} >Save change button


</>
);
};
SpreadSheet.propTypes = {
resourceTypes: PropTypes.objectOf(String),
channelGroupId: PropTypes.string,
planId: PropTypes.string,
invalidCells: PropTypes.objectOf(String),
setInValidCell: PropTypes.func,
costData: PropTypes.arrayOf(Object),
};
SpreadSheet.defaultProps = {
resourceTypes: {},
channelGroupId: ‘’,
planId: ‘’,
invalidCells: {},
setInValidCell: PropTypes.func,
costData: {},
};
export default SpreadSheet;
export { SpreadSheet as PureSpredSheet };

I have removed some of the code due to Company Policy
Consider button as

Hi @siddhantjain15298

Can you please try to simplify the code and put it into jsfiddle for example? It would be very helpful.

Hi @adrian.szymanski Can know the lifecycle of handsontable like function called first in sequence manner?

Hi @siddhantjain15298

Here you can read about all the events and hooks: https://handsontable.com/docs/events-and-hooks/#overview. What can be also useful for you is afterInit and beforeInit hooks:

Hello @adrian.szymanski We are facing render in handsontable Actually we create a Handsontable Wrapper and using it and passing Ref and function via props So
<><SpreadSheet /> -- ---> This is a wrapper of handsontable <button disabled={SheetisValid} > Submit Data</button> </. —> this is wrapper for handsontable
so i am changing a disabled state of button from false to true in afterValidate && afterChange function when i use dragToFill functionality first time on table it pass null to all cell not considering a filled value??

Hi @siddhantjain15298

Thank you for the detailed description of your issue, but we still need the code demo to see what’s going on.

@adrian.szymanski Do i know where i put Button disabled state in react so that this situation never comes? Actually i put code above but cannot make working on jsfiddle?

Hi @siddhantjain15298

We need more help regarding this case. It can be simplified demo which will show just the issue that you have.

Hi @adrian.szymanski
I think i found the issue my table running one step behind. Any solution to that?!
So when i drag to fill first value it fill null value and when i remove that first value then drag to fill that value then it fills previous value

import React, { useState, useRef } from ‘react’;
import { Button } from ‘@dentsu-ui/components’;
import { Spreadsheet } from ‘@dentsu-ui/spreadsheet’;
import { HyperFormula } from ‘hyperformula’;

const Table = () => {
const hotRef = useRef(null);
const [tableData, setTableData] = useState([]);

// Spredsheet is vaild
const [sheetIsValid, setSheetIsValid] = useState(false);

// Invaild cells
const [invalidCells, setInvalidCells] = useState(new Set());

// Update invalid cells set after cell validation has run
const afterValidate = (isValid, value, row, prop) => {
const hot = hotRef.current.hotInstance;
console.log(‘hello–>’, isValid);
const cellMeta = hot.getCellMeta(row, hot.propToCol(prop));
const data = { col: cellMeta.visualCol, row: cellMeta.visualRow };
const updatedInvalidCells = invalidCells;

if (isValid) {
  updatedInvalidCells.forEach((cell) => {
    if (cell.col === data.col && cell.row === data.row) {
      updatedInvalidCells.delete(cell);
    }
  });
} else {
  updatedInvalidCells.add(data);
}

setInvalidCells(updatedInvalidCells);
setSheetIsValid(updatedInvalidCells.size === 0);

};

// Add invalid classes back to invalid cells
const highlightInvalidCells = () => {
const hot = hotRef.current.hotInstance;

invalidCells.forEach((data) => {
  const cell = hot.getCell(data.row, data.col);
  !cell.classList.contains('htInvalid') && cell.classList.add('htInvalid');
});

};

// Highlight the invalid cells
const afterChange = (changes) => {
if (changes && changes.length) {
highlightInvalidCells();
}
};

return (
<>
<Spreadsheet
ref={hotRef}
data={tableData}
minRows={10}
rowHeaders
width=“100%”
height=“400”
stretchH=“all”
dataSchema={{ id: null, name: { first: null, last: null }, address: null }}
colHeaders={[‘ID’, ‘First Name’, ‘Last Name’, ‘Address’]}
columns={[
{ type: ‘numeric’ },
{ type: ‘numeric’ },
{ type: ‘numeric’ },
{ type: ‘numeric’, data: ‘address’ },
]}
minSpareRows={1}
afterValidate={afterValidate}
afterChange={afterChange}
formulas={{
engine: HyperFormula,
}}
/>
Save
</>
);
};

export default Table;

firstissue|690x276

HI @adrian.szymanski here is the demo: https://jsfiddle.net/sid15298/jred47gf/ for above issue
Steps to replicate: -

  1. enter value on handsontable
  2. drag to fill that value in any direction
  3. then it will fill null value instead of that target value

Hi @siddhantjain15298

Thank you for the demo. We’ll check it and get back to you.

Also, I will close that topic as it’s duplicate of this issue: Drag to fill and hyper formulas funcitonality is not working

Hi @adrian.szymanski No no open that topic u can close this topic as that topic is mentioned in my jira tickets that’s why