mui-x icon indicating copy to clipboard operation
mui-x copied to clipboard

[data grid] Extract value in DataGrid with valueGetter

Open tsafadi opened this issue 1 year ago • 5 comments

The problem in depth

I am writing a custom search component because I don't like the look of the quickFilter. I have a wrapper component around the DataGrid. Inside this component I am doing the following:

const filteredData = React.useMemo(() => {
        let result= props.rows;

        // Apply search filter
        if (tableOptions.search) {
            const searchValue = tableOptions.search.toLowerCase();
            result = result?.filter((row) => {
                // Check each column for the search term
                return props.columns.some((column) => {
                    const value = row[column.field] as string;
                    return value?.toLowerCase().includes(searchValue);
                });
            });
        }

        return result;
    }, [tableOptions, props.rows, props.columns]);

This all works fine until I am using a valueGetter. How would I implement this?

Your environment

`npx @mui/envinfo`
System:
    OS: Windows 11 10.0.22631
  Binaries:
    Node: 18.17.1 - C:\Program Files\nodejs\node.EXE
    npm: 10.2.1 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.0.5 - ~\AppData\Roaming\npm\pnpm.CMD
  Browsers:
    Chrome: Not Found
    Edge: Chromium (123.0.2420.97)
  npmPackages:
    @emotion/react: 11.11.3 => 11.11.3
    @emotion/styled: 11.11.0 => 11.11.0
    @mui/base:  5.0.0-beta.37
    @mui/core-downloads-tracker:  5.15.11
    @mui/lab: 5.0.0-alpha.166 => 5.0.0-alpha.166
    @mui/material: 5.15.11 => 5.15.11
    @mui/private-theming:  5.15.14
    @mui/styled-engine:  5.15.14
    @mui/system: 5.15.11 => 5.15.11
    @mui/types:  7.2.14
    @mui/utils: 5.15.11 => 5.15.11
    @mui/x-data-grid:  7.4.0
    @mui/x-data-grid-premium: 7.4.0 => 7.4.0
    @mui/x-data-grid-pro:  7.4.0
    @mui/x-date-pickers: 6.19.5 => 6.19.5
    @mui/x-license: ^7.2.0 => 7.2.0
    @types/react: 18.2.58 => 18.2.58
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: 5.3.3 => 5.3.3

Search keywords: DataGrid ValueGetter Value Order ID: 89911

tsafadi avatar May 16 '24 10:05 tsafadi

Hey @tsafadi What is it that you do not like about the built-in filter? We do have a recipe on how to achieve a very similar thing in the docs: example. Would that be a sufficient implementation for your use-case?

michelengelen avatar May 16 '24 10:05 michelengelen

Hello @michelengelen, Thanks for the provided example. Unfortunately, having the filter outside of the table is not sufficient. The looks of it just does not fit into the overall product design. We are using the outline variant and other customizations which I probably won't be able to achieve with the MUI filter.

I extended my filter function which works for now but I am not sure if I covered all edge cases:

const filteredData = React.useMemo(() => {
        let result= props.rows;

        // Apply search filter
        if (tableOptions.search) {
            const searchValue = tableOptions.search.toLowerCase();
            result = result?.filter((row) => {
                // Check each column for the search term
                return props.columns.some((column) => {
                    const value = row[column.field] as unknown;
                    const rawValue = value as string;

                    const finalValue = column?.valueGetter
                        ? (column.valueGetter(value as never, row, column, props.apiRef!) as string)
                        : rawValue;

                    return finalValue?.toLowerCase().includes(searchValue);
                });
            });
        }

        return result;
    }, [tableOptions, props.rows, props.columns, props.apiRef]);

I am not sure about the apiRef since it could be undefined (not sure why it does not take undefined) and I am also not sure about the type casting I am doing.

It would be pretty cool, if MUI DataGrid would provide a filter prop such that users could use their own filter component and simply pass the string as a prop.

tsafadi avatar May 16 '24 10:05 tsafadi

We do have the Quick filter, which basically does what you are trying to achieve.

Moving the textbox outside of the data grid is just one example of implementing a custom field for it. You can still use an input that sits in the toolbar area, or you can just use the setQuickFilterValues method from the apiRef.

I have built a quick demo showcasing a multiselect component to apply predefined filter values for the quickfilter: Quickfilter demo

This can be customized with basically anything.

michelengelen avatar May 16 '24 13:05 michelengelen

Great, thanks so much for providing this!

However, I do have some cases where I would need to extract the value from the valueGetter as I have it in my example above. Is there any way extracting it or is my solution the only way?

tsafadi avatar May 16 '24 14:05 tsafadi

It would be one option, but it will not be very performant if your dataset gets bigger. You can just use the quickfilter as it will apply it on the value that is received from valueGetter as well.

For a simple use-case like this extracting the value is not needed.

I have updated my demo with a different dataset to showcase this. Here is a short video as well: https://github.com/mui/mui-x/assets/32863416/ab2feec3-9eef-4b2e-a23d-516bc6d33cb1

michelengelen avatar May 16 '24 14:05 michelengelen

The issue has been inactive for 7 days and has been automatically closed.

github-actions[bot] avatar May 23 '24 15:05 github-actions[bot]