Closed mgodf closed 4 years ago
Actually I was able to get the desired effect by passing an implementation of the IFormulaParser
interface into Spreadsheet
.
The problem is, that I am still unable to get a cell to update when it contains an expression that is dependent on another cell value. I can update the data property underneath, but it still does not update the displayed value until it is selected again.
// Custom Formula Parser
const getFormulaParser = () =>{
const fp = {};
fp.parse = (exp) => { return exp + "!!!"; }
fp.on = (sig,cb) => {}
return fp;
}
// Custom Cell Viewer
const CellView = () => {
return ({getValue, cell, column, row, formulaParser}) =>
( <div> { formulaParser.parse(cell.value) +" ("+ column + ", " + row + ")!!"} </div> )
};
// Initialize empty data with custom cell viewer
const getInitialData = () =>{
const initialData = [];
const num_cols = 2;
const num_rows = 2;
for(let r=0; r<num_rows; r+=1) {
var row = [];
for(let c=0; c<num_cols; c+=1) {
row.push ({ value: "" , DataViewer: CellView()});
}
initialData.push(row);
}
return initialData;
};
//App with data bound by 'useState' hook
const simpleAppView = () =>{
const [data, setData] = useState(getInitialData());
return(<Spreadsheet data={data} formulaParser={getFormulaParser()}
onCellCommit={(prevCell, nextCell, coords) => {
// Do some update with data and nextCell.value
// ....
setData(data);
/>);
}
Hey @mgodf, thank you for the detailed bug report. I'll give it a look this weekend and update here.
Hey @mgodf, I looked into your code and I found that once written correctly it actually works:
The fixes I made:
data
is provided to the component you must provide onChange
to the component. In your case, it should be setData
.import React, { useState } from "react";
import Spreadsheet from "react-spreadsheet";
const COLUMNS = 2;
const ROWS = 2;
const DataViewer = ({ getValue, cell, row, column }) => {
const value = getValue({ data: cell, row, column });
// Shows alternate value
return value && `${value}!`;
};
// Custom Cell Viewer
const getInitialData = () => {
const initialData = [];
for (let r = 0; r < ROWS; r += 1) {
const row = [];
for (let c = 0; c < COLUMNS; c += 1) {
row.push({ value: "", DataViewer });
}
initialData.push(row);
}
return initialData;
};
// App with data bound by 'useState' hook
const SimpleAppView = () => {
const [data, setData] = useState(getInitialData());
return (
<Spreadsheet
// Provide data to spreadsheet
data={data}
// Update data state when spreadsheet changes
onChange={setData}
/>
);
};
Let me if that works for you if you have further questions you are welcome to ask here. If you encounter a new problem please open a new issue.
In case you have issues with dependant value try to use the getComputedValue
utility:
import React, { useState } from "react";
import Spreadsheet from "react-spreadsheet";
import { getComputedValue } from "react-spreadsheet/dist/util"
const COLUMNS = 2;
const ROWS = 2;
const DataViewer = ({ getValue, cell, row, column, formulaParser }) => {
const value = getComputedValue({ data: cell, row, column, formulaParser });
// Shows alternate value
return value && `${value}!`;
};
// Custom Cell Viewer
const getInitialData = () => {
const initialData = [];
for (let r = 0; r < ROWS; r += 1) {
const row = [];
for (let c = 0; c < COLUMNS; c += 1) {
row.push({ value: "", DataViewer });
}
initialData.push(row);
}
return initialData;
};
// App with data bound by 'useState' hook
const SimpleAppView = () => {
const [data, setData] = useState(getInitialData());
return (
<Spreadsheet
// Provide data to spreadsheet
data={data}
// Update data state when spreadsheet changes
onChange={setData}
/>
);
};
export default createFixture({
component: Test,
});
First of all, thanks for maintaining such a nice library.
I'm trying to react-spreadsheet with a custom DataViewer that will show a transformed version of the data entered into the cell. The problem is that the DataViewer does not update until it is selected again.
I tried to boil it down into a simplified version that shows my issue (this one just appends a
!
after the text) but I'd be happy to share any details.(ps. I understand that capturing a global ref to spreadsheet is probably not the right way to handle this. I'd be very grateful for a proper example!)
1.) Start
2.) Press
a
3.) Press
enter
(Expect to see updated cell view)4.) Press
up-arrow
to re-select cell (oh there, it is!)