WHICH VERSION OF REACT ARE YOU USING?
Officially Supported:
[x] v0.14.x
WHICH BROWSER ARE YOU USING?
Officially Supported:
[ ] IE 9 / IE 10 / IE 11
[ ] Edge
[x] Chrome
I'm submitting a ... (check one with "x")
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/adazzle/react-data-grid/blob/master/CONTRIBUTING.md
Current behavior
If a column is filtered or sorted, and someone tries to edit a cell, the cell does not reflect the edited changes - it goes back to its previous value. If the grid is not filtered or the column is not sorted, then it is editable.
Expected/desired behavior
A cell should be editable both filters and sorting is on. We can sort it manually re:https://github.com/adazzle/react-data-grid/issues/532 if we only have either one of those features, but not both.
Reproduction of the problem
If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem.
What is the expected behavior?
What is the motivation / use case for changing the behavior?
If anyone has any workarounds, I'd be very grateful! 馃檹
Thanks for putting up this bug - it helped me find a bug in my app :)
The way I worked around it was
handleRowUpdated event passes the rowIdx, key and the updated value, so I find the right row to update by using the rowGetter methodselectBy: (keys : ...Thanks @supamanda ! I found a different solution than yours but it still works!
If anyone's interested in the solution:
this.state.rows, instead, always refer to getRows getRows() {
return Selectors.getRows(this.state);
}
handleGridRowsUpdated , handleFilterChange, handleGridSort, should be the same as the demo examplethis.state.originalRows which is just a copy of your original rowsclearFilters, return this.state.rows to be the original rowsIf you are using redux you can dispatch an action and reload the rows. Let's say that the rows in the redux store are the originalRows. Not sure if this is the best way, but it works.
onRowsUpdated({ rowIds, updated } ) {
dispatch({
type: UPDATE_ROWS,
rowIds,
updated
});
}
@mi-lee I am using ES6. Can you tell me how to import Selectors?
Presently I am doing
import`{ Toolbar, Data: {Selectors} } from 'react-data-grid-addons'
which is throwing an error saying unexpected token
@beckmeindia is it because of the backtick after import ?
Hey,
No the backtick is a typo in the question posted.
I think the way Data: { Selectors} is written is unusual with respect to ES6 import statement syntax.
Can you suggest an alternative way of writing this part only?
Thanks
@beckmeindia It should work if you've compiled ES6.
Another way is
var ReactDataGrid = require('react-data-grid-addons')
var Toolbar = ReactDataGrid.Toolbar
var Selectors = ReactDataGrid.Data.Selectors
Thanks.
I think this should work. Will try it!
To build off of @mi-lee's comment, you should reference Selectors.getRows(this.state) in your handleGridRowsUpdated function instead of this.state.rows.slice() _(if you are following this example_: example13-all-features).
When I was making edits on a datagrid with an active filter, this.state.rows.slice()was not returning the id I had anticipated. The fromRow and toRow props were returning a row index relative to the filtered selection, but I was checking this index against the entire data set (instead of the filtered one. Using Selectors.getRows(this.state) solves this issue, because it returns the filtered subset.
My function looks something like this:
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
let rows = Selectors.getRows(this.state)
for (let i = fromRow; i <= toRow; i++) {
let rowToUpdate = rows[i]
let updatedRow = update(rowToUpdate, {$merge: updated})
rows[i] = updatedRow
}
this.setState({ rows })
// adding my id field to the object
updated.id = rows[fromRow].id
// passing the updated data to my handler function
this.props.handleUpdate(updated)
}
P.S. the update function I'm using is from immutability-helper (per the guidance of the react docs).
Above solution works but when i remove the filter or sort it only kept the last filter results instead of showing the actual row with edited values.
Here is how i solved the problem (note i had my own Id column to identify the actual row):
for (let i = fromRow; i <= toRow; i++) {
let rowToUpdate = filterSortRow[i];
let actualRowIndex = this.getActualRowIndexById(rows, rowToUpdate.id);
//update actual row;
let actualRowToUpdate = rows[actualRowIndex];
let actualUpdatedRow = update(actualRowToUpdate, {$merge: updated});
rows[actualRowIndex] = actualUpdatedRow;
// update filter row list
let updatedRow = update(rowToUpdate, {$merge: updated});
filterSortRow[i] = updatedRow;
}
this.setState({ rows });
};
getActualRowIndexById(list, id){
for (let i = 0; i < list.length; i++) {
let row = list[i];
if(row.id == id){
return i;
}
}
}
Most helpful comment
Thanks @supamanda ! I found a different solution than yours but it still works!
If anyone's interested in the solution:
this.state.rows, instead, always refer togetRowshandleGridRowsUpdated,handleFilterChange,handleGridSort, should be the same as the demo examplethis.state.originalRowswhich is just a copy of your original rowsclearFilters, returnthis.state.rowsto be the original rows