Is your feature request related to a problem? Please describe.
every time i update the rowData all of my detail panel auto close.
Describe the solution you'd like
I would like that my detail panel woul be able to stay open on the arriving of new rowData
+1, it would be awesome if the rendering could be separated between row and detailPanel.
In the meantime, is there any workaround, like using a collapse component?
Same issue, would appreciate any workaround or ideas
Also have the same problem. What I did was to mutate the state directly of the input inside my detailPanel. This isn't a good React practice though
@VicenteQueiroz could you explain that a little bit more?
Of course @rkulinski. In my parent component i have the state with all the data for the table. My table has a detail panel with an input. The onChange handler function sets the data to the state in the parent component. Now every time I did an input change the detail panel closed
Now in the handler function instead of doing the classic:
const {inputData} = this.state
inputData = evt.target.value
this.setState({inputData})
I mutate the state directly:
const inputData = this.state.inputData
inputData = evt.target.value
this.setState({inputData})
And this fixed that issue of closing the panel. Let me know if this worked for you as well
Hmm. I haven't tried it yet. But it seems odd. The only difference I can see is that first code sample uses destructing assignment and the other one not. I don't see how does it change anything. Didn't you mean to write this.state.inputData = inputData?
Has nobody found a workaround for that issue yet?
I have the same issue. This feature could be a great addition to material-table.
if you could add an 'expanded' prop like material ui does for their expansion panels that'd be great.
that way when we change the state we can at-least hold onto a list of panels that should be expanded.
A workaround for this:
Let's say you have the following data that you want to show in the table. You keep the data in the state, it is being updated, but you don't want details panels to collapse when the data is updated (when size on object with uid 'b' changes from 3 to 4):
[
{uid: "a", size: 2, ...},
{uid: "b", size: 3, ...},
{uid: "c", size: 2, ...},
...
]
Solution: Detailed map + Simple array
Add a Map to the state, use uid as map keys and push respective values to the map.
"a" => {uid: "a", size: 2, ...},
"b" => {uid: , size: 3, ...},
"c" => {uid: , size: 2, ...},
Create a separate array in the state that will only contain uid values:
this.setState({
array: Array.from(this.state.map.keys())
}); // ["a", "b", "c"]
Pass this.state.array as a data source to MaterialTable.
The array doesn't contain all the data (just the uid). In the table render function, take the uid and get the actual row data from the map:
render: rowData => {
let actualRowData = this.state.map.get(rowData.uid);
...
// use actualRowData.size
...
}
With this new setup, when you do any changes to the original data in the state, which is stored in the Map, the array that is passed to the table won't update, and panels won't collapse.
@lukavida This could definitely be a solution, but it still doesn't seem right to do all that work for such a simple task. Like @chrisLoPresti said, this would be a great addition to the current library.
@gtupak well of course it doesn鈥檛 seem right.
But those that desperately need the solution (like I needed it) will be thankful that someone created a workaround and invested time to create a detailed explanation of it.
Also facing the same issue. Pumping this up - this would be a great feature to have.
Same issue here
The problem is, that material-table mutates the objects and adds a tableData object to the objects passed in the data prop. This tableData object contains stuff like id and showDetailPanel. By updating the data, this tableData object is lost and a new one will be added, but the default is collapsed.
showDetailPanel is the function returned from detailPanel prop for that row.
So to persist the expansion, you need to keep track of this tableData object. This is connected to an underlying problem with the mutation of the user data and will be fix in future releases, once the issues and PRs are taken care of as far as I know.
To keep track of them you could to it like this:
const [data,setData]= React.useState([MY_ITEMS]);
const updateData = (index, newValue) => {
setData(prevData => {
const newData = prevData.map(d => ({...d}));
newData[index].name = newValue;
return newData;
});
}
// To manually expand a row, do it like this:
const expendRow = (index) => {
setData(prevData => {
const newData = prevData.map(d => ({...d}));
newData[index].tableData.detailPanel = (row) => <div>{JSON.stringify(row)}</div> // YOUR_DETAIL_PROP_FUNCTION:
return newData;
});
}
return <MaterialTable data={data} .../>
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You can reopen it if it required.
Bumping, one of the most important open issues currently imo.
I wrapped material table and I tracked opened panels with ref. I know that it's not the best solution, but at least it works
import React, { useEffect, useRef } from "react"
import MaterialTable from "material-table"
export function CustomMaterialTable(props) {
const tableRef = useRef()
const openedPanels = useRef({})
const oldFunction = useRef()
useEffect(() => {
if (!oldFunction.current) {
oldFunction.current = tableRef.current?.onToggleDetailPanel
}
if (oldFunction.current === tableRef.current?.onToggleDetailPanel) {
tableRef.current.onToggleDetailPanel = (path, render) => {
if (
tableRef.current.props.data[path[0]].tableData
.showDetailPanel
) {
delete openedPanels.current[path[0]]
} else {
openedPanels.current = {
...openedPanels.current,
[path[0]]: true,
}
}
oldFunction.current(path, render)
}
}
}, [tableRef])
return (
<MaterialTable
tableRef={tableRef}
{...props}
data={
props.data?.map((d, i) => ({
...d,
tableData: {
showDetailPanel: openedPanels.current[i]
? props.detailPanel
: null,
},
})) || []
}
/>
)
}
Most helpful comment
I have the same issue. This feature could be a great addition to material-table.