react-data-table-component
react-data-table-component copied to clipboard
Editable input field within data table column
Dear Sir or Madam,
First of all, thank you so much for creating and maintaining this library. It's really an awesome library.
Recently, I wanted to include editable input fields within data table column as shown in the image highlighted in yellow below.
I tried a lot of different ways but I am getting an issue whereby the entire DataTable refreshes and I lost the focus of the input field whenever I update the state.
Below are the codes that I have tried:
// State
state = {
itemDetailList: [
{id: 0, item: 'Item', expDate: '01/01/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 21}},
{id: 1, item: 'Item1', expDate: '01/02/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 22}},
{id: 2, item: 'Item2', expDate: '01/03/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 203}},
{id: 3, item: 'Item3', expDate: '01/04/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 205}},
{id: 4, item: 'Item4', expDate: '01/05/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 5, item: 'Item5', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 6, item: 'Item6', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 7, item: 'Item7', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 8, item: 'Item8', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 9, item: 'Item9', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 10, item: 'Item10', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 11, item: 'Item11', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
{id: 12, item: 'Item12', expDate: '01/06/2020', unitCost: 15, quantity: {pcs: 5, set: 10, ctn: 20}},
],
};
// Populate table columns
const itemDetailTableColumns = [
{
name: 'Item',
selector: 'item',
sortable: true,
},
{
name: 'Expiry Date',
selector: 'expDate',
sortable: true,
},
{
name: 'Unit Cost',
selector: 'unitCost',
sortable: true,
},
{
name: 'Quantity',
selector: 'quantity',
cell:(row) => (
<Aux>
<Form.Group as={Row} className="align-items-center m-l-0">
<Col className="px-0">
<Form.Control
type="text"
key={"ctn" + row.id}
name={"ctn" + row.id}
id={"ctn" + row.id}
placeholder=""
value={this.state.itemDetailList[row.id].quantity.ctn}
onChange={(event) => {
var updatedItemDetailList = this.state.itemDetailList.slice()
updatedItemDetailList[row.id].quantity.ctn = event.target.value
this.setState({
itemDetailList: updatedItemDetailList
})
}}
/>
</Col>
<Form.Label column>
CTN
</Form.Label>
</Form.Group>
<Form.Group as={Row} className="align-items-center m-l-0">
<Col className="px-0">
<Form.Control
type="text"
key={"set" + row.id}
name={"set" + row.id}
id={"set" + row.id}
placeholder=""
value={this.state.itemDetailList[row.id].quantity.set}
onChange={(event) => {
console.log(row)
//console.log(event.target.value)
//console.log(this.updatedItemDetailList)
var updatedItemDetailList = this.state.itemDetailList.slice()
updatedItemDetailList[row.id].quantity.set = event.target.value
this.setState({
itemDetailList: updatedItemDetailList
})
}}
/>
</Col>
<Form.Label column>
SET
</Form.Label>
</Form.Group>
<Form.Group as={Row} className="align-items-center m-l-0">
<Col className="px-0">
<Form.Control
type="text"
key={"pcs" + row.id}
name={"pcs" + row.id}
id={"pcs" + row.id}
placeholder=""
value={this.state.itemDetailList[row.id].quantity.pcs}
onChange={(event) => {
console.log(row)
//console.log(event.target.value)
//console.log(this.updateditemDetailList)
var updatedItemDetailList = this.state.itemDetailList.slice()
updatedItemDetailList[row.id].quantity.pcs = event.target.value
this.setState({
itemDetailList: updatedItemDetailList
})
}}
/>
</Col>
<Form.Label column>
PCS
</Form.Label>
</Form.Group>
</Aux>
),
sortable: true,
},
];
// Data Table
<DataTable
noHeader={true}
columns={itemDetailTableColumns}
data={this.state.itemDetailList}
pagination={true}
progressShowTableHead
/>
Thank you. Best Regards, Jack Tiong
Thanks! Glad you are finding RDT useful 😄
So, it looks like you're updating data={this.state.itemDetailList}
every time you type into a field. This will cause RDT to re-render. This is by design and how React works.
Instead of directly updating state on your inputs just have a save button on your row or cell that does the state update instead. Also when you update your state you may want to look into some immutable patterns for updating state as you are currently mutating your state which React will not work well with. https://daveceddia.com/why-not-modify-react-state-directly/
I hope this helps and good luck!
One final thing that may be helpful. This is a different table library 😬 but you can see here how they are handling row updates
https://material-ui.com/components/tables/
I'm going to re-open this as documentaion and I'll also see about adding an example this to the storybooks for inline editing
Thank you so much @jbetancur I tried a lot of different libraries (including material-ui table) and it seems like only react-table (https://github.com/tannerlinsley/react-table) library can fulfill most of my requirements as it allows a certain column or a certain table cell to be disabled and the state will be updated each time when an input loss its focus. Pretty cool I must say.
Actually, I think this may also be a potential feature for a new onRowUpdate
prop to make things easier
https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/editable-data
Interesting. I'll see about feature flagging this in the future for editable columns!
@jbetancur Is it possible to use select in editable columns?
Thanks! Glad you are finding RDT useful 😄
So, it looks like you're updating
data={this.state.itemDetailList}
every time you type into a field. This will cause RDT to re-render. This is by design and how React works.Instead of directly updating state on your inputs just have a save button on your row or cell that does the state update instead. Also when you update your state you may want to look into some immutable patterns for updating state as you are currently mutating your state which React will not work well with. daveceddia.com/why-not-modify-react-state-directly
I hope this helps and good luck!
@jbetancur making save
button makes ui not reactive. Sometimes it's unacceptable. Is there any way to make it so, that cells are updated, rather then re-mounted?
I have a similar problem. I have inputs in the row and every time I write a text it loses focus after the first character. The same code works for reactstrap table or by using simple divs. Placing a save button is unacceptable in my case
@jbetancur Hey, is there any updates on this feature?
this feature would be really nice
Not sure if its helpful to anyone, I ended up using onBlur to apply the changes to state once they had clicked away, one issue is if they click on a button a the first next click, it wont trigger a button click but instead just the blur. It seems to work "ok" though.