Reputation: 858
Working Code :https://codesandbox.io/s/broken-https-2i454?file=/src/App.js
I'm using Material UI in my reactjs project and I'm trying the update the value entered inside a textfield of a table using onChange function for the textfield, currently the value is present inside an array of array,I want to update the componentQuantity
, I'm aware of passing the event to get the event.target.value
, but what is the correct way to update the specific value of the textfield present inside a array of array. Please someone help me out here.
class TabData extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
data: [
{
BomComponentCode: "345543",
BomComponentName: "COMP1",
BomComponentRefUOM: "gm",
rowId: 0,
consumptionBatchNumbers: [
{
componentBatchNumber: "20",
componentQuantity: 2
},
{
componentBatchNumber: "21",
componentQuantity: 3
}
]
},
//2nd cloumn
{
BomComponentCode: "5543",
BomComponentName: "COMP2",
BomComponentRefUOM: "KG",
rowId: 1,
consumptionBatchNumbers: [
{
componentBatchNumber: "22",
componentQuantity: 4
},
{
componentBatchNumber: "23",
componentQuantity: 5
}
]
}
],
renderState: false
};
}
handleUpdate = (index, Code) => {
this.setState({
renderState: Code
});
};
handleChange = (e) => {
console.log(e.target.value)
};
render() {
const { classes } = this.props;
const { data, renderState } = this.state;
return (
<div className={classes.list}>
<React.Fragment>
<Grid
item
xs={12}
sm={12}
md={12}
className={classes.grid}
style={{ paddingLeft: "0" }}
>
<p variant="h6" className={classes.font}>
Table Details
</p>
<span className={classes.borders}></span>
</Grid>
<div>
<TableContainer component={Paper} className={classes.paper}>
<Table className={classes.table} aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell> Number</TableCell>
<TableCell> Text</TableCell>
<TableCell>UOM</TableCell>
<TableCell> Batch </TableCell>
<TableCell> Quantity</TableCell>
<TableCell>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
<React.Fragment>
{data.map((item, i) => (
<React.Fragment>
<TableRow key={i}>
<TableCell scope="row" align="left">
{item.BomComponentCode}
</TableCell>
<TableCell align="left">
{item.BomComponentName}
</TableCell>
<TableCell align="left">
{item.BomComponentRefUOM}
</TableCell>
<TableCell>
{item.consumptionBatchNumbers.map((row, i) => (
<div key={i}>
<TableCell align="left">
{row.componentBatchNumber}
</TableCell>
</div>
))}
</TableCell>
{renderState === item.BomComponentCode ? (
<TableCell align="left">
{item.consumptionBatchNumbers.map((row, indi) => (
<div key={indi}>
<input
// value={row.componentQuantity}
onChange={(e) =>
this.handleChange(e)
}
defaultValue={row.componentQuantity}
/>
</div>
))}
</TableCell>
) : (
<TableCell align="left">
{item.consumptionBatchNumbers.map((row, indi) => (
<div key={indi}>
<TableCell align="left">
{row.componentQuantity}
</TableCell>
</div>
))}
</TableCell>
)}
<TableCell>
<button
onClick={() =>
this.handleUpdate(i, item.BomComponentCode)
}
>
Update
</button>
</TableCell>
</TableRow>
</React.Fragment>
))}
</React.Fragment>
</TableBody>
</Table>
</TableContainer>
</div>
<Grid container justify="center">
<Grid
item
xs={4}
sm={4}
md={2}
style={{
textAlign: "center",
padding: "1rem"
}}
>
<button >Close</button>
</Grid>
</Grid>
</React.Fragment>
</div>
);
}
}
export default (TabData);
Upvotes: 1
Views: 68
Reputation: 5497
To modify the value in the deeply nested array you need indexes . Once you have the indexes its easier to change the values .
Change the handleChange
method to accept the row and deeply nested row's indexes.
onChange={(e) => this.handleChange(e, i, indi)}
Once you have the indexes we can deep clone the original state to create a new copy of state and mutate it directly .
handleChange = (e, rowIndex, consumptionBatchIndex) => {
// deep clone the data
const clonedData = JSON.parse(JSON.stringify(this.state.data));
clonedData[rowIndex].consumptionBatchNumbers[
consumptionBatchIndex
].componentQuantity = e.target.value;
this.setState({
data: clonedData
});
};
Now we can read the value in the input as
<input
value={row.componentQuantity}
onChange={(e) => this.handleChange(e, i, indi)}
/>
Upvotes: 2