Reputation: 773
I have implemented the datepicker and timepicker with add,delete buttons in each row. When I click on add, will add new row and delete will delete row.
I have the code link https://codesandbox.io/s/zen-water-tfyoz?fontsize=14&hidenavigation=1&theme=dark
But how to handle the state for multiple datepicker and timepicker,
When change the date, it doesnot reflect the change in field. https://codesandbox.io/s/zen-water-tfyoz?fontsize=14&hidenavigation=1&theme=dark
Upvotes: 0
Views: 2810
Reputation: 135
The reason that the date field's changes aren't reflected in the UI is that you've implemented it as a controlled component (you are setting the value of each DatePicker based on the corresponding value in the state and updating the state when you change the value, which effectively synchronizes the component with the state, more or less), whereas the TimePickers do change in the UI when a new time is chosen because they are implemented as uncontrolled components. Controlled components are often the best method, but your date component isn't updating on change because there are problems in your handleDatePicker function, as pointed out by Kaca992's answer.
If you don't know much about controlled vs uncontrolled components, see here.
As for how to handle the state for multiple DatePickers and TimePickers, personally I'd recommend that you store them as an array of rows in the state. For example, this would be a default state:
this.state = {
rows: [
{
date: new Date(),
start: moment(),
end: moment(),
}
]
}
Each row element in the array would correspond to a row in the table, and you can just use array.map to render each row as a component that contains the DatePicker, TimePickers, and buttons, and then just send the array index along with the new value to your onChange functions so that the correct row's changes can be reflected in the new state.
This would require a bit of a re-write of your DynamicDateTimePicker class, but the logic would be much simpler and more readable than how you currently have it structured.
Upvotes: 0
Reputation: 2267
So the problem is in your renderRowData function:
<td key={`tableview-td-${rowId}-${index}`}>
{column.dataFieldId === "pickdate" ? (
<DatePicker
locale="en-GB"
className="datepicker"
name={"pickdate_" + rowId}
onChange={e =>
this.handleDatePicker(
e,
"pickdate_" + rowId,
column.dataFieldId,
row
)
}
value={this.state.pickdate}
/>
)
For value u use this.state.pickdate, but when value changes you set it with:
handleDatePicker = (value, name, field, row) => {
this.props.handleInputChange(value, field, row);
console.log("data", value, "for", name);
this.setState({ [name]: value });
};
wich means that your state is now:
{
["pickdate_" + rowId]: value // where row is selected row
}
you need to change your datepicker to access value like this:
<td key={`tableview-td-${rowId}-${index}`}>
{column.dataFieldId === "pickdate" ? (
<DatePicker
locale="en-GB"
className="datepicker"
name={"pickdate_" + rowId}
onChange={e =>
this.handleDatePicker(
e,
"pickdate_" + rowId,
column.dataFieldId,
row
)
}
value={this.state["pickdate_" + rowId] || this.defaultPickDate} // this will take new selected value or default if there is none
/>
)
Working example: https://codesandbox.io/s/funny-fog-1v9o3
Upvotes: 1