2

在实施自定义过滤器选项之前,温度(数字类型)显示为附加了“° C”的字符串,但仍保留该值,因为它能够相应地排序(升序和降序)。实现自定义过滤器选项后,我不再能够根据值进行过滤,而是根据从 customBodyRender 返回的字符串进行过滤。例如,如果我将最小值指定为 3,则不会返回 20 和 10 之类的值,因为它现在似乎是按字母数字排序的。当我删除 customBodyRender 时,它工作得很好。

如何让 MUI 数据表以我想要的方式呈现,同时保留实际值本身的排序?我粘贴了下面的代码。由于我是新来的反应,我将继续做更多的研究并随着时间的推移更新问题。

const columns = [
    {name: "Temperature", options:{
      filter: true,
      customBodyRender: (value) => {
        return (value + "° C")
      },
      filterType: 'custom',
      filterList: [],
      customFilterListOptions: {
        render: value => {
          if (value[0] && value[1]) {
            return `Min Temp: ${value[0]}, Max Temp: ${value[1]}`;
          } else if (value[0]) {
            return `Min Temp: ${value[0]}`;
          } else if (value[1]) {
            return `Max Temp: ${value[1]}`;
          }
          return false;
        },
        update: (filterList, filterPos, index) => {
          console.log('customFilterListOnDelete: ', filterList, filterPos, index);

          if (filterPos === 0) {
            filterList[index].splice(filterPos, 1, '');
          } else if (filterPos === 1) {
            filterList[index].splice(filterPos, 1);
          } else if (filterPos === -1) {
            filterList[index] = [];
          }

          return filterList;
        },
      },
      filterOptions: {
        names: [],
        logic(value, filters) {
          if (filters[0] && filters[1]) {
            return (value < filters[0]) || value > filters[1];
          } else if (filters[0]) {
            return value < filters[0];
          } else if (filters[1]) {
            return value > filters[1];
          }
          return false;
        },
        display: (filterList, onChange, index, column) => (
          <div>
            <FormLabel>Temperature</FormLabel>
            <FormGroup row>
              <TextField
                label="min"
                value={filterList[index][0] || ''}
                onChange={event => {
                  filterList[index][0] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%', marginRight: '5%' }}
              />
              <TextField
                label="max"
                value={filterList[index][1] || ''}
                onChange={event => {
                  filterList[index][1] = event.target.value;
                  onChange(filterList[index], index, column);
                }}
                style={{ width: '45%' }}
              />
            </FormGroup>
          </div>
        ),
      },
    }}
]
4

2 回答 2

1

我在您的代码中发现了两个小问题。

第一个:中的渲染函数customFilterListOptions应该返回一个字符串或字符串[](参见文档)。第二个:在逻辑功能中filterOptions,需要在比较之前将values和转换为数字。filters

如果您有任何问题,请告诉我。

现在应该可以工作了:

import React from "react";
import ReactDOM from "react-dom";
import MUIDataTable from "mui-datatables";
import { TextField, FormLabel, FormGroup } from "@material-ui/core";
import { toNumber } from "lodash";

import "./styles.css";

const TEMPERATURE_PREFIX = "° C";

function App() {
  const columns = [
    {
      name: "city",
      label: "City",
      options: {
        filter: true,
        sort: false
      }
    },
    {
      name: "temp",
      label: "Temperature",
      options: {
        sort: true,
        customBodyRender: value => {
          return value + TEMPERATURE_PREFIX;
        },
        filter: true,
        filterType: "custom",
        filterList: [],
        customFilterListOptions: {
          render: value => {
            if (value[0] && value[1]) {
              return `Min Temp: ${value[0]}, Max Temp: ${value[1]}`;
            } else if (value[0]) {
              return `Min Temp: ${value[0]}`;
            } else if (value[1]) {
              return `Max Temp: ${value[1]}`;
            }
            return [];
          },
          update: (filterList, filterPos, index) => {
            console.log(
              "customFilterListOnDelete: ",
              filterList,
              filterPos,
              index
            );

            if (filterPos === 0) {
              filterList[index].splice(filterPos, 1, "");
            } else if (filterPos === 1) {
              filterList[index].splice(filterPos, 1);
            } else if (filterPos === -1) {
              filterList[index] = [];
            }

            return filterList;
          }
        },
        filterOptions: {
          names: [],
          logic(value, filters) {
            const temperature = toNumber(
              value.replace(TEMPERATURE_PREFIX, "")
            );
            const lower = toNumber(filters[0]);
            const upper = toNumber(filters[1]);
            if (lower && upper) {
              return temperature < lower || temperature > upper;
            } else if (lower) {
              return temperature < lower;
            } else if (upper) {
              return temperature > upper;
            }
            return false;
          },
          display: (filterList, onChange, index, column) => (
            <div>
              <FormLabel>Temperature</FormLabel>
              <FormGroup row>
                <TextField
                  label="min"
                  value={filterList[index][0] || ""}
                  onChange={event => {
                    filterList[index][0] = event.target.value;
                    onChange(filterList[index], index, column);
                  }}
                  style={{ width: "45%", marginRight: "5%" }}
                />
                <TextField
                  label="max"
                  value={filterList[index][1] || ""}
                  onChange={event => {
                    filterList[index][1] = event.target.value;
                    onChange(filterList[index], index, column);
                  }}
                  style={{ width: "45%" }}
                />
              </FormGroup>
            </div>
          )
        }
      }
    }
  ];

  const data = [
    { city: "Yonkers", temp: 3 },
    { city: "Hartford", temp: 11 },
    { city: "Tampa", temp: 25 },
    { city: "Dallas", temp: 30 }
  ];

  const options = {
    filterType: "checkbox"
  };

  return (
    <div className="App">
      <MUIDataTable
        title={"Employee List"}
        data={data}
        columns={columns}
        options={options}
      />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

( https://codesandbox.io/s/competent-kirch-uc01b )

于 2019-12-20T14:14:37.200 回答
0

在选项中添加下面的代码。

options={{
  sort: true,
  sortOrder: { name: 'id', direction: 'desc' },
}}
于 2022-01-12T17:00:28.603 回答