Comments (12)
Thanks for raising this.
You could try to use setItemAt or setItemPropertyAt to update the dataSource - since onEditComplete has the info you need to do the update. Please let us know how this goes - and if you have any issue, it would help to have a code sample to better understand what you are trying to do. Thanks
from reactdatagrid.
setItemAt
would work for single edits which is great but there are still some other concerns that would be solved if the data source was truly controlled:
- External changes to the data (e.g. apollo cache updates, websocket events, etc)
- Needing to share the entire data set with multiple tables, graphs, etc.
You could potentially add a setItems
method but that would still not be very ideal since we would constantly need to keep the internal data source in sync with the other one (e.g. apollo cache).
Alternatively you can support an object like dataSource which has the following structure:
{
data: [],
getData: () => []
}
This would be an additive change to the API without needing a major version bump.
from reactdatagrid.
Not sure I fully follow your proposal - can you clarify please?
You're suggesting we add an API method to retrieve the currently loaded dataSource? Something like https://reactdatagrid.io/docs/api-reference#method-getItemAt but to retrieve the whole data the grid stores internally?
Or are you proposing the dataSource
prop accepts a different shape or returns a different object when it's a function?
from reactdatagrid.
Im proposing something like the following:
const columns = [...];
const App = () => {
const [data, setData] = useState([]);
const [count, setCount] = useState(0);
const [loading, setLoading] = useState(false);
const dataSource = useMemo(() => ({
data,
count,
loadData: ({ skip, sortInfo, limit }) => {
return fetch(DATASET_URL + '?skip=' + skip + '&limit=' + limit + '&sortInfo='+JSON.stringify(sortInfo))
.then(response => {
const totalCount = response.headers.get('X-Total-Count');
response.json().then((data) => {
setData(prevData => [...prevData, ...data]);
setCount(parseInt(totalCount));
});
})
}
}), [data, count])
return (
<div>
<h3>Live pagination example - infinite loading, 50 per page</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
pagination
livePagination
dataSource={dataSource}
onLoadingChange={setLoading}
/>
</div>
);
}
This is just a proposal, I'm sure there are gonna be some other edge cases but doing something like that gives us full control of the data.
from reactdatagrid.
Hi, following up on this since I was able to get this sort of working via bi-directional syncing the internal data source to local state. Unfortunately, the only way to do that is via onLoadingChange
.
const dataSource: TypeDataSource = async ({ skip, limit }) => {
return {
data: await fetchMockData({ skip, limit }),
count: 1000
};
};
const SyncedDataSource = () => {
const [data, setData] = useState<any[]>([]);
const [count, setCount] = useState<number>(0);
const [loading, setLoading] = useState(false);
const [
gridRef,
setGridRef
] = useState<MutableRefObject<TypeComputedProps | null> | null>(null);
useEffect(() => {
if (gridRef?.current && !isEqual(data, gridRef.current.data)) {
gridRef.current.setOriginalData(data);
}
}, [gridRef, data]);
return (
<>
<Box padding="space1" display="flex" alignItems="center" gap="space1">
<SecondaryButton
onClick={() => {
setData((prevData) => prevData.slice(1, prevData.length));
}}
>
Delete First Row (External)
</SecondaryButton>
<SecondaryButton
onClick={() => {
setData((prevData) => {
const [first, ...rest] = prevData;
return [{ ...first, title: uniqueId('Edit ') }, ...rest];
});
}}
>
Edit First Row (External)
</SecondaryButton>
<SecondaryButton
onClick={() => {
gridRef?.current?.setOriginalData([]);
gridRef?.current?.setSkip?.(0);
}}
>
Reset
</SecondaryButton>
<Box flex={1}>
<Text align="right" bold>
Showing {data.length} out of {count} Records
</Text>
</Box>
</Box>
<ReactDataGrid
onReady={setGridRef}
columns={columns}
dataSource={dataSource}
loading={loading}
onLoadingChange={(loading: boolean) => {
if (gridRef?.current && !loading) {
setData(gridRef.current.data);
setCount(gridRef.current.count);
}
setLoading(loading);
}}
pagination
livePagination
/>
</>
);
};
I think this solution is OK but depending on the onLoadChange
callback for data synchronization isn't very intuitive. Another possible solution (if you don't want to go the controlled data source way in my comment above), adding an onDataSourceChange
callback would be a good enough interim solution.
<ReactDataGrid
onReady={setGridRef}
columns={columns}
dataSource={dataSource}
loading={loading}
onLoadingChange={setLoading}
onDataSourceChange={({ data, count }) => {
setData(data);
setCount(count);
}}
pagination
livePagination
/>
from reactdatagrid.
Glad to hear you managed to find a solution!
I think an even better solution would be to just pass the current data
array to the dataSource
prop.
So besides of having access to skip, limit, etc, you will also have access to data
const dataSource = ({skip, limit, data }) => {
return fetch(...).json().then(newData => {
console.log('full data will be', [...data, ...newData])
return newData
})
}
<DataGrid dataSource={dataSource} />
from reactdatagrid.
I like that idea as well. I do have 1 question:
If I load 3 pages and data
has 60 records in it. If I re-sort the table, data
should be an empty array then correct?
from reactdatagrid.
Yes, sorting should trigger a full reload of the datasource, so it will reset skip to 0.
Additionally, we have scrollTopOnSort=true, which is what you want most of the time
from reactdatagrid.
Thinking more about this, your proposed solution wouldn't solve the case where the data was manipulated via setItemAt
or setItemPropertyAt
. Something like onDataSourceChange
would better solve this use case.
from reactdatagrid.
with v4.0.23
we added the currentData
property (array) to the object that is being passed in to the dataSource
function
from reactdatagrid.
the currentData
array does include the items changed via setItemAt
and setItemPropertyAt
from reactdatagrid.
So pagination is working?
I am using community version.
const dataSource = async ({ skip, limit }) => {
const searchCriteria = {
page: skip / limit + 1,
pageSize: limit
}
const data = await apiClient.post(
"Right/GetPagedRecords",
searchCriteria
)
const result = {
data: data.data,
count: data.totalRecords
};
console.log('result=================', result)
return result
};
The count is 22 but it shows 10.
Now sure what is happening.
from reactdatagrid.
Related Issues (20)
- Autosize all columns function crashes when grid has more then 15 columns and columnVirtualization is enabled HOT 1
- The Clear/Clear All filter menu crashes after changing enableFiltering to false and then returning it back to true.
- Is this library actively maintained?
- Incorrect onRowDoubleClick behaviour with scroll HOT 1
- Duplicate cells when scrolling
- Combine filtering and loadNode
- 💡 Add tooltip to cell rows
- Running setColumnsSizesAuto with virtualization does not size columsn not in view
- 🚨 Bugs: Broken contact email ahead of renewal HOT 1
- 🐛 Bug: Grid Scrolls to the Left When Select Filter is Opened
- ❓ Can you please answer my email 🙏🏿 HOT 4
- Grid crashes if you add `showEmptyRows` to a treeGrid
- 🐛 Bug caused by Typo in reactdatagrid/community-edition/packages/NumericInput/src /NumberInput.tsx HOT 1
- 🐛 Bug: DateFilter autocompletes on first character of the input
- 🐛 Bug: drag & drop callbacks return incorrect data objects (with undocumented work-arounds)
- 💡 Customize height of header row & filter row
- 🐛 BUG: flex prop fails to interpret numeric arguments presented as strings properly as numbers - a single entry in columnData as a string causes the entire flex to fail.
- 🐛 Bug: No way to see which row is focus in select filter list
- 🐛 Bug: Cannot read properties of null (reading 'filter' or reading 'push') with createRoot - react@18
- number column in some group conditions sorts by first digit, not by number HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reactdatagrid.