【问题标题】:How to filter DataGrid columns on click of an external button in mui如何在单击 mui 中的外部按钮时过滤 DataGrid 列
【发布时间】:2022-11-09 21:07:21
【问题描述】:

假设我有一个像这样的数据网格表(来自官方 MUI 文档):

import * as React from 'react';
import { DataGrid, GridToolbar } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin'];

export default function ControlledFilters() {
  const { data } = useDemoData({
    dataSet: 'Employee',
    visibleFields: VISIBLE_FIELDS,
    rowLength: 100,
  });

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        {...data}
        components={{
          Toolbar: GridToolbar,
        }}
      />
    </div>
  );
}

现在假设我想通过单击按钮来过滤此表中的“名称”列。单击该按钮时,应该给出一个字符串,比如说“Ray”。单击此按钮时,我想自动过滤表,以便仅显示包含字符串“Ray”的“名称”列中的每个值。

到目前为止我的方法

我尝试使用 react 中的 useState 和 DataGrid 中的 filterModel 道具,以便按下按钮过滤表格,如下所示:

  ....

  const [filt, setFilt] = useState('') // Initialize it with an empty filter
  const handleClick = () => {
      setFilt('Ray');
  };

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        {...data}
        components={{
          Toolbar: GridToolbar,
        }}
        filterModel={{
          items: [{ columnField: 'name', operatorValue: 'contains', value: filt },
          ]
        }}
      />

    <Button onClick={handleClick}>Change Filter</Button>
    </div>
  );
}

这可行,但这种方法的问题在于它会锁定所有其他过滤器,并且过滤器基本上卡在“名称”列上,用户现在只能使用按钮来过滤列。它甚至不允许我移除过滤器。

我也尝试过 onFilterModelChange 道具,但它没有用;老实说,我对如何在这种特定情况下使用它感到困惑。任何帮助,将不胜感激。

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    你很亲密。我相信您需要形成整个 items 数组,而不仅仅是过滤器对象的一部分。

    setFilt([{ columnField: 'name', operatorValue: 'contains', value: "Ray"}]) 而不是setFilt("Ray") 以及{ columnField: 'name', operatorValue: 'contains', value: filt}

    您可以通过在filterModel 中设置items: [] 来重置过滤器。

    CodeSandbox Example 具有单个过滤条件。

    (如果您在代码沙箱上有任何编译问题,我必须安装 @mui/material v5.9.2 而不是 v5.9.3 才能使其工作)

    const [filt, setFilt] = useState([])
    
    <DataGrid 
      {...data} 
      filterModel={{
        items: filt
      }}
    />
    <Button
      onClick={() =>
        setFilt([
          {
            columnField: "name",
            operatorValue: "startsWith",
            value: "A"
          }
         ])
      }
    >
      Name Starts With A
    </Button>
    <Button
      onClick={() => setFilt([])}
    >
      Reset Filters
    </Button>
    

    奖励:使用按钮进行多重过滤

    CodeSandbox Example 带有按钮的多过滤器网格。

    只有Pro version of MUI 才能进行多重过滤。如果没有 Pro 版本,则在第一个过滤器之后添加的任何其他过滤器都会被忽略(如您所见)。

    这就是我使用@mui/x-data-grid-pro 和 3 个不同的按钮想出的,每个按钮都应用一个独特的过滤器:

    const [filt, setFilt] = useState([])
    
    <DataGridPro
      {...data}
      filterModel={{
        items: filt,
        GridLinkOperator: GridLinkOperator.And
      }}
    />
    <Button
      onClick={() =>
        setFilt([
          ...filt,
          { 
             id: 1, 
             columnField: "rating", 
             operatorValue: ">", 
             value: 3 
          }
        ])
      }
    >
      Rating Greater Than 3
    </Button>
    <Button
      onClick={() =>
        setFilt([
          ...filt,
          {
            id: 2,
            columnField: "name",
            operatorValue: "startsWith",
            value: "A"
          }
        ])
      }
    >
      Name Starts With A
    </Button>
    <Button
      onClick={() => setFilt([])}
    >
      Reset Filters
    </Button>
    

    需要注意的一个警告 --- 使用多重过滤时,您需要在 items 数组中的每个过滤器对象中添加一个 id

    例如

    [
      { id: 1, columnField: 'rating', operatorValue: '>', value: 3 },
      { id: 2, columnField: 'name', operatorValue: 'startsWith', value: "A" }
    ]
    

    【讨论】:

    • 谢谢,这行得通!此外,我想出了另一种方法,它涉及的代码行数相对较少。我会将其发布为答案。
    • 你找到更好的方法了吗?我很好奇!
    • 哦,我的错,我完全忘记发布答案了!我马上贴出来
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2021-04-01
    • 1970-01-01
    • 2012-08-29
    相关资源
    最近更新 更多