反应表动态下拉可重用的自定义过滤器

时间:2018-10-10 11:00:36

标签: reactjs react-table

我有一个反应表,我想在其中添加一些自定义过滤

我要实现的是一个下拉选择器,该选择器会动态填充所有可用选项

我快到了,并且有一个可行的解决方案,但是我真正想做的是使我的customFilter可重用于三个字段(名字,姓氏和年龄)中的每一个-当前可以使用,但是经过硬编码每个值

所以这行

.map(item => item.lastName)

需要像

.map(item => item.{accessor})

那是行不通的,但是我想我可以获取每个字段的访问器值,然后它才是真正的动态和可重用

const customFilter = ({ filter, onChange }) => {
    return (
      <select
        onChange={event => onChange(event.target.value)}
        style={{ width: "100%" }}
        value={filter ? filter.value : "all"}
      > 
        <option value="all">Show All</option>
        {testData
          .map(item => item.lastName)

          .filter((item, i, s) => s.lastIndexOf(item) == i)
          .map(function (value) {
            log.debug('renderItem: ', value);
            return (
              <option key={value} value={value}>
                {value}
              </option>
            );
          })}
      </select>
    );
  };

  const testData = [
    { firstName: 'Aang', lastName: 'Smith', age: '19' },
    { firstName: 'Appa', lastName: 'Baker', age: '3' },
    { firstName: 'Asami', lastName: 'Smith', age: '19' },
    { firstName: 'Azula', lastName: 'Baker', age: '19' },
    { firstName: 'Bolin', lastName: 'Smith', age: '20' },
    { firstName: 'Jinora', lastName: 'Baker', age: '19' },
    { firstName: 'Katara', lastName: 'Smith', age: '8' },
    { firstName: 'Korra', lastName: 'Baker', age: '19' },
    { firstName: 'Lin Beifong', lastName: 'Smith', age: '19' },
    { firstName: 'Momo', lastName: 'Baker', age: '19' },
    { firstName: 'Mai', lastName: 'Smith', age: '8' },
    { firstName: 'Mako', lastName: 'Baker', age: '29' },
    { firstName: 'Naga', lastName: 'Smith', age: '19' },
    { firstName: 'Pabu', lastName: 'Baker', age: '19' },
    { firstName: 'Sokka', lastName: 'Smith', age: '39' },
    { firstName: 'Suki', lastName: 'Baker', age: '8' },
    { firstName: 'Tenzin', lastName: 'Smith', age: '19' },
    { firstName: 'Toph Beifong', lastName: 'Baker', age: '19' },
    { firstName: 'Ty Lee', lastName: 'Smith', age: '49' },
    { firstName: 'Uncle Iroh', lastName: 'Baker', age: '59' },
    { firstName: 'Varrick', lastName: 'Smith', age: '19' },
    { firstName: 'Zhu Li', lastName: 'Baker', age: '8' },
    { firstName: 'Zuko', lastName: 'Smith', age: '19' }
  ];


  const columns = [
    {
      Header: "First Name",
      accessor: "firstName", 
      filterMethod: (filter, row) =>
        row[filter.id].startsWith(filter.value) &&
        row[filter.id].endsWith(filter.value)
    }, {
      Header: "Last Name",
      id: "lastName",
      accessor: d => d.lastName,
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ filter, onChange })
    }, {
      Header: "Age",
      accessor: "age",
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ filter, onChange })
    }
  ]


  return (
    <div>
    <ReactTable
      data={testData}
      filterable
      defaultFilterMethod={(filter, row) =>
        String(row[filter.id]) === filter.value}
      columns={columns}
      defaultPageSize={10}
      className="-striped -highlight"
    />
      <br />
    </div>
  );

1 个答案:

答案 0 :(得分:1)

找到了解决方案

因此,对于每个列过滤器,我都给了它一个fieldName变量-然后我可以调用它来更改值并使其可重用

所以这行

.map(item => item.lastName)

成为这个

.map(item => item[fieldName])

效果很好:-)

const customFilter = ({ fieldName, filter, onChange }) => {

    return (
      <select
        onChange={event => onChange(event.target.value)}
        style={{ width: "100%" }}
        value={filter ? filter.value : "all"}
      > 
        <option value="all">Show All</option>
        {testData
          .map(item => item[fieldName])

          .filter((item, i, s) => s.lastIndexOf(item) == i)
          .map(function (value) {
            log.debug('renderItem: ', value);
            return (
              <option key={value} value={value}>
                {value}
              </option>
            );
          })}
      </select>
    );
  };

  const testData = [
    { firstName: 'Aang', lastName: 'Smith', age: '19' },
    { firstName: 'Appa', lastName: 'Baker', age: '3' },
    { firstName: 'Asami', lastName: 'Smith', age: '19' },
    { firstName: 'Azula', lastName: 'Baker', age: '19' },
    { firstName: 'Bolin', lastName: 'Smith', age: '20' },
    { firstName: 'Jinora', lastName: 'Baker', age: '19' },
    { firstName: 'Katara', lastName: 'Smith', age: '8' },
    { firstName: 'Korra', lastName: 'Baker', age: '19' },
    { firstName: 'Lin Beifong', lastName: 'Smith', age: '19' },
    { firstName: 'Momo', lastName: 'Baker', age: '19' },
    { firstName: 'Mai', lastName: 'Smith', age: '8' },
    { firstName: 'Mako', lastName: 'Baker', age: '29' },
    { firstName: 'Naga', lastName: 'Smith', age: '19' },
    { firstName: 'Pabu', lastName: 'Baker', age: '19' },
    { firstName: 'Sokka', lastName: 'Smith', age: '39' },
    { firstName: 'Suki', lastName: 'Baker', age: '8' },
    { firstName: 'Tenzin', lastName: 'Smith', age: '19' },
    { firstName: 'Toph Beifong', lastName: 'Baker', age: '19' },
    { firstName: 'Ty Lee', lastName: 'Smith', age: '49' },
    { firstName: 'Uncle Iroh', lastName: 'Baker', age: '59' },
    { firstName: 'Varrick', lastName: 'Smith', age: '19' },
    { firstName: 'Zhu Li', lastName: 'Baker', age: '8' },
    { firstName: 'Zuko', lastName: 'Smith', age: '19' }
  ];


  const columns = [
    {
      Header: "First Name",
      accessor: "firstName", 
      filterMethod: (filter, row) =>
        row[filter.id].startsWith(filter.value) &&
        row[filter.id].endsWith(filter.value)
    }, {
      Header: "Last Name",
      id: "lastName",
      accessor: d => d.lastName,
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ fieldName:'lastName', filter, onChange })
    }, {
      Header: "Age",
      accessor: "age",
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ fieldName:'age', filter, onChange })
    }
  ]


  return (
    <div>
    <ReactTable
      data={testData}
      filterable
      defaultFilterMethod={(filter, row) =>
        String(row[filter.id]) === filter.value}
      columns={columns}
      defaultPageSize={10}
      className="-striped -highlight"
    />
      <br />
    </div>
  );