首页 > 解决方案 > 如何在material-ui datagrid中实现搜索?

问题描述

我正在尝试在 Material-UI 数据网格中实现快速过滤/搜索选项。截至目前,datagrid 没有搜索选项。我正在使用Material-UI-Search-Bar库来添加搜索字段和功能。我在自定义工具栏中有这个,但不幸的是这不起作用,因为它与状态有关。我无法集中文本字段。在我的代码下面

...

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>
)

标签: reactjsdatagridmaterial-ui

解决方案


有时 Material-UI-Search-Bar 库会中断,所以最好使用这个:

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…&quot;
        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>
  );
}

如果demo不够用,需要实现原生版本,请到# 2842点赞。


推荐阅读