Reputation: 1162
I'm trying to implement quick filter/search option in Material-UI datagrid. As of now datagrid doesn't have search option. I'm using Material-UI-Search-Bar library to add search field and functionality. I'm having this inside custom toolbar, but unfortunately this doesn't work because it has something to do with state. I'm not able to focus the text field. Below my code
...
const requestSearch = (searchedVal: string) => {
const filteredRows = tableData.filter((o: any) => {
return Object.keys(o).some((k: any) => {
return o[k].toString().toLowerCase().indexOf(searchedVal.toLowerCase()) != -1;
})
});
console.log(filteredRows);
// setTableData(filteredRows);
};
const cancelSearch = () => {
setSearchText("");
requestSearch(searchText);
};
const CustomToolbar = () => {
<div className='p-6'>
<div> ... </div>
<SearchBar
value={searchText}
onChange={(searchVal: string) => requestSearch(searchVal)}
onCancelSearch={() => cancelSearch()}
/>
</div>
}
...
return (
<div ... >
<div style={{ height: 500, width: '100%', backgroundColor: 'white' }}>
<DataGrid
rows={tableData}
columns={columns}
components={{ Toolbar: CustomToolbar }}
...
/>
</div>
</div>
)
Upvotes: 5
Views: 30561
Reputation: 1242
In MUI data grid quick search is not very prominent in the documentation but they have added in running demo examples. You just need to add this prop to the data grid and you are done. even you can set debouncing time here.
componentsProps={{
toolbar: {
showQuickFilter: true,
quickFilterProps: { debounceMs: 500 },
},
}}
Upvotes: 9
Reputation: 129
Sometimes Material-UI-Search-Bar library breaks so it's better to use this:
import * as React from 'react';
import IconButton from '@mui/material/IconButton';
import TextField from '@mui/material/TextField';
import {
DataGrid,
GridToolbarDensitySelector,
GridToolbarFilterButton,
} from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';
import ClearIcon from '@mui/icons-material/Clear';
import SearchIcon from '@mui/icons-material/Search';
import { createTheme } from '@mui/material/styles';
import { createStyles, makeStyles } from '@mui/styles';
function escapeRegExp(value: string): string {
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
const defaultTheme = createTheme();
const useStyles = makeStyles(
(theme) =>
createStyles({
root: {
padding: theme.spacing(0.5, 0.5, 0),
justifyContent: 'space-between',
display: 'flex',
alignItems: 'flex-start',
flexWrap: 'wrap',
},
textField: {
[theme.breakpoints.down('xs')]: {
width: '100%',
},
margin: theme.spacing(1, 0.5, 1.5),
'& .MuiSvgIcon-root': {
marginRight: theme.spacing(0.5),
},
'& .MuiInput-underline:before': {
borderBottom: `1px solid ${theme.palette.divider}`,
},
},
}),
{ defaultTheme },
);
interface QuickSearchToolbarProps {
clearSearch: () => void;
onChange: () => void;
value: string;
}
function QuickSearchToolbar(props: QuickSearchToolbarProps) {
const classes = useStyles();
return (
<div className={classes.root}>
<div>
<GridToolbarFilterButton />
<GridToolbarDensitySelector />
</div>
<TextField
variant="standard"
value={props.value}
onChange={props.onChange}
placeholder="Search…"
className={classes.textField}
InputProps={{
startAdornment: <SearchIcon fontSize="small" />,
endAdornment: (
<IconButton
title="Clear"
aria-label="Clear"
size="small"
style={{ visibility: props.value ? 'visible' : 'hidden' }}
onClick={props.clearSearch}
>
<ClearIcon fontSize="small" />
</IconButton>
),
}}
/>
</div>
);
}
export default function QuickFilteringGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 100,
maxColumns: 6,
});
const [searchText, setSearchText] = React.useState('');
const [rows, setRows] = React.useState<any[]>(data.rows);
const requestSearch = (searchValue: string) => {
setSearchText(searchValue);
const searchRegex = new RegExp(escapeRegExp(searchValue), 'i');
const filteredRows = data.rows.filter((row: any) => {
return Object.keys(row).some((field: any) => {
return searchRegex.test(row[field].toString());
});
});
setRows(filteredRows);
};
React.useEffect(() => {
setRows(data.rows);
}, [data.rows]);
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid
components={{ Toolbar: QuickSearchToolbar }}
rows={rows}
columns={data.columns}
componentsProps={{
toolbar: {
value: searchText,
onChange: (event: React.ChangeEvent<HTMLInputElement>) =>
requestSearch(event.target.value),
clearSearch: () => requestSearch(''),
},
}}
/>
</div>
);
}
If the demo is not enough and a native version should be implemented, please go to #2842 and upvote.
Upvotes: 6