Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGridPro] Set multiple saved filters #3662

Closed
2 tasks done
lincolnmqs opened this issue Jan 18, 2022 · 13 comments
Closed
2 tasks done

[DataGridPro] Set multiple saved filters #3662

lincolnmqs opened this issue Jan 18, 2022 · 13 comments
Labels
component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user

Comments

@lincolnmqs
Copy link

lincolnmqs commented Jan 18, 2022

Order ID 💳

35305

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Summary 💡

I want to save the filter history for when I leave the page and come back, set the filters previously configured.

The problem in depth 🔍

Code used to loop through an object's keys and apply the "upsertFilterItem" method to insert an item into the filter:
image

Object added to filter:
image

In this example, the object being applied inside the "upsertFilterItem" method, is not adding the apiRef filter list.

Context 🔦

Is it possible to do it this way? Cycle through an object by entering previously saved filters before exiting the page.

This would be very useful to not have to configure filters all the time and be able to apply them to other pages.

Your environment 🌎

`npx @mui/envinfo`
  Don't forget to mention which browser you used.
  Output from `npx @mui/envinfo` goes here.
@lincolnmqs lincolnmqs added plan: Pro Impact at least one Pro user support: question Community support but can be turned into an improvement status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jan 18, 2022
@flaviendelangle
Copy link
Member

You can use apiRef.current.setFilterModel to pass to update the whole model at once.
Your usecase look a lot like #3593 which should be available in v5.4 in a few weeks.

@flaviendelangle flaviendelangle added component: data grid This is the name of the generic UI component, not the React module! support: Stack Overflow Please ask the community on Stack Overflow and removed support: question Community support but can be turned into an improvement status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jan 19, 2022
@mui mui deleted a comment from github-actions bot Jan 19, 2022
@github-actions github-actions bot removed the support: Stack Overflow Please ask the community on Stack Overflow label Jan 19, 2022
@lincolnmqs
Copy link
Author

@flaviendelangle Is it just to throw all this object from the photo below inside the method "setFilterModel"?

image

@flaviendelangle
Copy link
Member

flaviendelangle commented Jan 19, 2022

Yes
This object is the filterModel

@lincolnmqs
Copy link
Author

@flaviendelangle It's because this error is appearing, and I'm throwing the object inside.

image

Code:
image

@flaviendelangle
Copy link
Member

flaviendelangle commented Jan 19, 2022

Please provide a reproduction case, working with screenshots is not great.

If you want to initialize the filter when mounting the grid, use the initialState prop
If you want to set the filter model later, use apiRef.current.setFilterModel, but never inside the render method since it will not be ready for the 1st render

And, if, as I understand on your screenshot, you have an internal state with the model, use the filterModel and onFilterModelChange props to control the model.

The filtering doc has a new version released this week.
You can find it here for more details.

@michael-land
Copy link

@flaviendelangle Thank you for spending time to improve the docs

@lincolnmqs
Copy link
Author

lincolnmqs commented Jan 19, 2022

@flaviendelangle Sorry I didn't send all the code.

I managed to run the method, thanks.

Is it possible to execute a function after the DataGridPro is rendered? Because I need to call this function after rendering, so I can use "apiRef" and its "setFilterModel" method.

I used the DataGridPro's "onStateChange" property, and it worked, whenever it updates the state, it lists the filters with the data I set by "setFilterModel". But with that, in every change of state, it calls this method that I implemented and the navigation is not cool. Do you have any properties for an initial callback of the DataGridPro rendering?

@flaviendelangle
Copy link
Member

I feel like you are doing something wrong.
If you follow the doc page I linked above, you should not have a listen to onStateChange or call a function after the rendering of the grid.

@lincolnmqs
Copy link
Author

lincolnmqs commented Jan 19, 2022

@flaviendelangle I can't access the doc you linked above.

image

What is happening is that the "Table" button is where the DataGridPro is, and when I click on it, I call the "selectedFilters" function where it searches for the selected filters. However, when clicking on this button, what seems to me is that it is calling the function before the table exists (entering the table page), so there is no apiRef so far.

I needed to put a setTimeout to wait for the time to find the apiRef and be able to execute its methods.

image
image

The DataGridPro is inside the graphics state.

image

@flaviendelangle
Copy link
Member

Weird, it works on my computer... perhaps a problem with the preview on your browser language.


If you want to share your filters between your chart and your table tab, you should probably control the filters

<DataGrid
  filterModel={this.state.filters}
  onFilterModelChange={newModel => this.setState(prevState => ({ ...prevState, filters: newModel })
/>

And if the format of the filters is not the same for the table and the charts, you can add a conversion step (which would be a lot easier with hooks, I must admit that I'm not used to work with classes anymore).
Something like:

<DataGridWithChartFilterModel
  filterModel={this.state.filters}
  onFilterModelChange={newModel => this.setState(prevState => ({ ...prevState, filters: newModel })
/>


// And then `DataGridWithChartFilterModel` is just a wrapper to convert the filterModel
class DataGridWithChartFilterModel {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.rawFilters !== nextProps.filterModel) {
      return {
        rawFilters: nextProps.filterModel,
        filterModel: convertFilterModelFromChartFormatToGridFormat(nextProps.filterModel),
    }
  }

  handleFilterModelChange = (newModel) => {
    const rawFilters = convertFilterModelFromGridFormatToChartFormat(newModel);
    this.props.onFilterModelChange(rawFilters);
  }

  render() {
    return (
      <DataGrid
        {...this.props}
        onFilterModelChange={this.handleFilterModelChange}
        filterModel={this.state.filterModel}
      />
    )
  }
}

But you should avoid using imperative apis unless you absolutely need to.

@flaviendelangle
Copy link
Member

But we are entering React related topics, not DataGrid related topics here
For the DataGrid part, you should be good by passing a valid filterModel to the filterModel prop and updating your state with the onFilterModelChange prop.

@lincolnmqs
Copy link
Author

@flaviendelangle But using the filterModel, I can't delete 1 item from the filter. See the code and the result.

image
image

@flaviendelangle
Copy link
Member

flaviendelangle commented Jan 20, 2022

  • Do not access the state directly, always use a selector
-const filterModel = this.apiRef.current.state.filters.filterModel;
+const filterModel = gridFilterModelSelector(this.apiRef.current.state)
  • Why use deleteFilters AND update manually your state ?

Either call apiRef.current.deleteFilters and the Grid will call onFilterModelChange to tell you to update your state
Or you update manually your state without calling apiRef.current.deleteFilters
But in your screen, you are calling apiRef.current.deleteFilters, the grid does not update its internal model because you are controlling it, instead it is calling your onFilterModelChange. So when you access the grid internal model it is not updated yet.

Are you familiar with what a control mode is ?

By the way, I will stop helping you based on screenshot, the discussion can continue for days like this.
If you create a reproduction case, I will make it work to show the good approach.
But I can't help you based on small fragments of the code. I don't even know if you added a onFilterModelChange to update your state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user
Projects
None yet
Development

No branches or pull requests

3 participants