MUI DataGrid - 打开 GridColumnsPanel

Wal*_*rsi 5 reactjs material-ui mui-datatable

在 MUI DataGrid 中,通过单击任何标题列上的选项菜单,您可以访问列可见性面板。

但我还没有找到从网格外部显示此面板的方法。这个想法是有一个按钮,当单击该按钮时,可以显示面板。即使它保留在网格内的位置

这将避免为此目的构建组件。

例子: 例子

Lin*_*ste 6

网格的这一部分称为GridPreferencesPanel。您可以使用showPreferences网格 API 上的功能强制打开它。以下是MUI 源代码的文档:

/**
 * The preferences panel API interface that is available in the grid [[apiRef]].
 */
export interface GridPreferencesPanelApi {
    /**
     * Displays the preferences panel. The `newValue` argument controls the content of the panel.
     * @param {GridPreferencePanelsValue} newValue The panel to open. Use `"filters"` or `"columns"`.
     */
    showPreferences: (newValue: GridPreferencePanelsValue) => void;
    /**
     * Hides the preferences panel.
     */
    hidePreferences: () => void;
}
Run Code Online (Sandbox Code Playgroud)

相同的函数用于打开过滤器菜单和列菜单,因此您需要传递正确的参数来确定要显示的菜单。您的示例图像描绘了列菜单。如果您使用 TypeScript,则应该导入GridPreferencePanelsValue枚举并调用showPreferences(GridPreferencePanelsValue.columns). 使用纯 JavaScript,您可以调用showPreferences("columns").


要在网格上下文内部(例如在自定义组件中)执行此操作Toobar,您将使用useGridApiContext挂钩来访问该函数。

import * as React from "react";
import { Button } from "@mui/material";
import {
  GridToolbarContainer,
  GridPreferencePanelsValue,
  useGridApiContext
} from "@mui/x-data-grid";

export const CustomToolbar = () => {
  const apiRef = useGridApiContext();

  const handleClick = () => {
    apiRef.current?.showPreferences(GridPreferencePanelsValue.columns);
  };

  return (
    <GridToolbarContainer>
      <Button onClick={handleClick}>Show Columns</Button>
    </GridToolbarContainer>
  );
};
Run Code Online (Sandbox Code Playgroud)
<DataGrid
  components={{
    Toolbar: CustomToolbar
  }}
  // your other props
/>
Run Code Online (Sandbox Code Playgroud)

代码沙箱演示


为了将按钮放置在网格本身之外,您需要使用挂钩useGridApiRef(仅限专业版功能)。这将创建一个引用,您将传递给该引用DataGrid,但也允许您在父组件中使用该引用。

文档:在网格之外使用它

import * as React from "react";
import { Box, Button } from "@mui/material";
import {
  DataGridPro,
  GridPreferencePanelsValue,
  useGridApiRef
} from "@mui/x-data-grid-pro";

export const ParentComponent = () => {
  const apiRef = useGridApiRef();

  const handleClick = () => {
    apiRef.current?.showPreferences(GridPreferencePanelsValue.columns);
  };

  return (
    <Box>
      <Button onClick={handleClick}>Show Columns</Button>
      <Box sx={{ height: 400, width: "100%" }}>
        <DataGridPro
          apiRef={apiRef}
          // your other props
        />
      </Box>
    </Box>
  );
}
Run Code Online (Sandbox Code Playgroud)

代码沙箱演示

当然有一些解决方法可以避免使用专业版挂钩,但这是最干净的方法。


coo*_*ot3 1

我不确定我是否在文档中错过了它,但您似乎无法像使用过滤器面板那样使用网格 API 来控制默认 MUI“列可见性面板”的可见性。

但是,您可以向 DataGrid 提供您自己的 columnVisibilityModel,它将指示哪些列在网格中可见。这将使您可以从网格外部控制每列的​​可见性,但您必须创建自己的列可见性面板。

这是一个代码沙箱示例: https://codesandbox.io/s/mui-5-forked-zj4glu ?file=/src/ArrowPopper.tsx

代码:

import * as React from "react";
import { Box, Button, FormControlLabel, Popper, Switch } from "@mui/material";
import { DataGrid, GridColDef, GridValueGetterParams } from "@mui/x-data-grid";

const columns: GridColDef[] = [
  { field: "id", headerName: "ID", width: 90 },
  {
    field: "firstName",
    headerName: "First name",
    width: 150,
    editable: true
  },
  {
    field: "lastName",
    headerName: "Last name",
    width: 150,
    editable: true
  },
  {
    field: "age",
    headerName: "Age",
    type: "number",
    width: 110,
    editable: true
  },
  {
    field: "fullName",
    headerName: "Full name",
    description: "This column has a value getter and is not sortable.",
    sortable: false,
    width: 160,
    valueGetter: (params: GridValueGetterParams) =>
      `${params.row.firstName || ""} ${params.row.lastName || ""}`
  }
];

const rows = [
  { id: 1, lastName: "Snow", firstName: "Jon", age: 35 },
  { id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 },
  { id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 },
  { id: 4, lastName: "Stark", firstName: "Arya", age: 16 },
  { id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null },
  { id: 6, lastName: "Melisandre", firstName: null, age: 150 },
  { id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 },
  { id: 8, lastName: "Frances", firstName: "Rossini", age: 36 },
  { id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 }
];

export default function DataGridDemo() {
  const [columnVisibility, setColumnVisibility] = React.useState({
    id: true,
    firstName: true,
    lastName: true,
    age: true,
    fullName: true
  });

  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

  const toggleColumnVisibility = (e) => {
    setColumnVisibility((prev) => ({
      ...prev,
      [e.target.name]: e.target.checked
    }));
  };

  const handleClick = (event: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(anchorEl ? null : event.currentTarget);
  };

  const open = Boolean(anchorEl);

  return (
    <Box sx={{ height: 400, width: "100%" }}>
      <Button
        onClick={handleClick}
        variant="contained"
        sx={{
          mb: 2
        }}
      >
        Show Column Visibility
      </Button>
      <DataGrid
        rows={rows}
        columns={columns}
        pageSize={5}
        rowsPerPageOptions={[5]}
        checkboxSelection
        disableSelectionOnClick
        columnVisibilityModel={columnVisibility}
      />
      <Popper open={open} anchorEl={anchorEl}>
        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            backgroundColor: "white"
          }}
        >
          {columns.map((c) => (
            <FormControlLabel
              key={c.field}
              label={c.headerName}
              control={
                <Switch
                  name={c.field}
                  checked={columnVisibility[c.field]}
                  onChange={toggleColumnVisibility}
                />
              }
            />
          ))}
        </Box>
      </Popper>
    </Box>
  );
}
Run Code Online (Sandbox Code Playgroud)