I have a fairly simple datagrid table with the option to hide/show specific columns.
I want to save the state of the columns when a rerender occurs (in my case when the language is changed).
Here is a stripped down sample. Just hide a column and then click the button. The column-header change as expected but the hidden column reappears.
https://codesandbox.io/s/material-demo-forked-lq22m
I think I have to set the hide property correctly to the current state of the columns in my click handler:
const handleButtonClick = () => {
setColumnState((c) => c.map((d) => ({ ...d, hide:currentStateofHideForEachCol, headerName: "nombre" })));
};
But I cant find a way to access it.
Currently, by updating columnState you are forcing a rerender of a new grid instead of updating the current one, thus losing the state.
I changed your code behavior so it now uses GridColDef.renderHeader and React.useContext to change the column names based on the language without losing the grid's state.
In terms of saving the state of the grid, the whole state of the grid is not controllable, making it difficult to do so, particularly the columns' visibility is not accessible. However, other props (the sort, filter, and selection models) can be controlled. For example, you can control the page prop:
// This mimics the default page change behavior
const [currentPage, setCurrentPage] = useState(1);
const handleChangePage = useCallback(
(gridPageChangeParams)=> setCurrentPage(gridPageChangeParams.page),
[]
);
<DataGrid page ={currentPage} onPageChange={handleChangePage}
Related
I am using Ag-grid library for grid view in React app. Following is my Ag-Grid component:
const handleChanged = (gridOptions) => {
const selectedNodes = gridOptions.api.getSelectedNodes()
//TODO
}
<AgGridReact
data-testid="details-data"
columnDefs={DetailsColDef}
rowData={formatDetailsData(
data?.Response,
false
)}
rowSelection="single"
reactNext={true}
defaultColDef={defaultColDef}
onSelectionChanged={handleSelected}
suppressPaginationPanel={true}
domLayout="autoHeight"
suppressMaxRenderedRowRestriction={true}
rowBuffer={5}
suppressColumnVirtualisation={false}
debounceVerticalScrollbar={true}
alwaysShowVerticalScroll={true}
></AgGridReact>
Current Scenario: handleChanged is getting called when we click on Grid row.
Requirement: Need to call handleChanged event every time on multiple click at same time. Currently event is getting called first time only. If we click again on same row, it need's to be called.
You can call gridOptions.api.getSelectedNodes() inside onCellClicked. Every time the row/cell is clicked you will get the data
const onCellClicked = (e) => {
const selectedRows = gridOptions.api.getSelectedNodes();
console.log(selectedRows)
}
<AgGridReact
onCellClicked={onCellClicked}
....
>
</AgGridReact>
Check working example
I think you are trying to use onSelectionChanged out of its scope, if you need to see if a cell is clicked (any number of times, you can use the onCellClicked Event). there are multitudes of events that can be used if that doesn't suit your needs.
https://www.ag-grid.com/react-data-grid/grid-events/#reference-selection
Otherwise if you are going to use this event only one handy way would be to change the selected row at the end of your processing and making this process async. this would be be problematic if the user clicks the row you have chosen to set it to so not the optimal solution i would say.
https://www.ag-grid.com/react-data-grid/row-selection/#node-selection-api
I am using react-big-calendar I would like to know if it is possible to be able to render more information of each event in the calendar.
Its documentation is hard for me to understand, and I don't know what prop I have to use to make custom event content.
In this query, it says that it is possible to make an override component to the default one.
But I can't find an example to guide me, nor which props should I use to override within the calendar component.
what i want to achieveenter image description here
It is possible to override the 'event' display, in every view of the Calendar.
const MyMonthEventComponent = ({ event, isAllDay, ...props }) => // layout for event in 'month'
const MyWeekEventComponent = ({ event, isAllDay, ...props }) => // layout for event in 'week'
const MyDayEventComponent = ({ event, isAllDay, ...props }) => // layout for event in 'day'
// ...
const components = useMemo(() => ({
month: {
event: MyMonthEventComponent
},
week: {
event: MyWeekEventComponent
},
day: {
event: MyDayEventComponent
}
// or 'agenda' events, or an custom 'view' you define...
}), []);
// ...
<Calendar components={components} {...otherProps} />
The components prop points all of this out, though you are right that figuring out 'how' to construct an override is a little difficult, largely because so much can be overridden. The easiest way is to look at the source code on GitHub to find out what props are passed in to a particular component.
The biggest challenge to changing 'event' display is understanding base Calendar layout. Event display boundaries (width, height, placement), are dynamically calculated based upon available space. You typically display the absolute least amount of data necessary, for a user to identify an event, and provide other means for viewing additional detail. A common way to do this is by controlling the selected prop, by storing 'selected' in state and setting its value with the onSelectEvent prop (reading the documentation here will help). Once you are controlling selected you can use that state value to populate some other control area in your overall layout, providing a master/detail type view.
I am using Material-UI X Grid in a dynamic UI with data updating at ~1Hz. When the page re-renders with new data, any sorted or hidden columns return to their default, i.e. hidden columns are shown again and the columns re-sort to their default positions. Is there any way to stop this behavior and maintain the state selected by the user? I have searched the API documentation and Material-UI's support pages to no avail.
I received support from the Material UI team and am providing the answer here in case it can help someone else.
The issue was that I needed to maintain the columns prop outside of the component via the useState() hook. The basics for what worked for me are included below.
function Table(props) {
const [cols, setCols] = useState([]);
const [cols_loaded, setColsLoaded] = useState(false);
if(!cols_loaded){
setCols(funcToReturnCols());
}
const data = {columns: cols, rows: getRows(props)};
content = <div className="data-table">
<XGrid
{...data}
loading={data.rows.length === 0}
rowHeight={30}
autoHeight={true}
disableColumnMenu={true}
density={"compact"}
components={{
Toolbar: GridToolbar,
}}
/>
</div>
;
return content;
}
The documentation did in fact have a mention that the columns should be maintained outside of the component and that the intent was for them to only be included once, which is smarter anyways!
https://material-ui.com/components/data-grid/columns/
From the link above: "The columns prop should keep the same reference between two renders. The columns are designed to be definitions, to never change once the component is mounted. Otherwise, you take the risk of losing the column width state (if resized). You can create the array outside of the render function or memoize it."
i have some problems, i am using devextreme(Tagbox) dropdown, i have a list of my grid and filtered very well. but when i am refreshing the page filter is gone(the grid behavior seems like selectall from to my db) i am research on stack overflow this issue, some people says use localstorage, and i did it, but couldn't find any solutions i don't know whats the best way doing that,
i did selected target value and then pass to data my state, after that i don't know what will i do right now.. Thank you!
this my code;
<TagBox
dataSource={this.getRegions}
displayExpr="name"
valueExpr="id"
onValueChanged={this.onRegionChanged}
/>
onRegionChanged = (e) => {
LS._setItem("FilterRegion", e.value);
const FilteredRegion = LS._getItem("FilterRegion");
this.setState((prevState) => ({
...prevState.FilteredRegion,
FilterRegion: FilteredRegion,
}));
console.log(this.state.FilterRegion);
I am new to React and I stumbled upon react-dropdown-tree-select for a specific need I had allowing users to view data in Tree format for selection in DropDown. But, I want the users to only select 1 value at a time. How can i enforce that?
There is no such property available directly in react-dropdown-tree-select. But you can listen to onChange event and reset the entire data which you have passed in data props with the updated data with only one node selected.
Check the following code.
onChange = (currentNode) => {
// keep reference of default data structure.
const updatedData = this.props.defaultData;
// find node related to currentData in your tree and set checked property
this.setState({data : updatedData });
}
render = () => {
return (
<DropdownTreeSelect
data={this.state.data}
onChange={this.onChange}
/>
);
}
This will basically stop the user from selecting multiple options instead of disabling remainig item you are unselecting the previously selected items.
If you just want one element selected at a time you can use mode="radioSelect"