【问题标题】:How to use the search filter from outside the table?如何使用表外的搜索过滤器?
【发布时间】:2019-06-29 13:16:14
【问题描述】:

我正在使用antd 表。有没有办法可以在表外添加搜索过滤器并仍然在表中搜索?

Demo.

我在表格上方添加了一个输入字段。但我无法理解如何将其链接到antd 提供的搜索功能。我还为每一列添加了搜索过滤器,但也希望在外面有一个单独的字段。列过滤器工作正常。

为了方便参考,我也把演示代码贴在这里:

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, Input, Button, Icon } from "antd";
import Highlighter from "react-highlight-words";

const data = [
  {
    key: "1",
    name: "John Brown",
    age: 32,
    address: "New York No. 1 Lake Park"
  },
  {
    key: "2",
    name: "Joe Black",
    age: 42,
    address: "London No. 1 Lake Park"
  },
  {
    key: "3",
    name: "Jim Green",
    age: 32,
    address: "Sidney No. 1 Lake Park"
  },
  {
    key: "4",
    name: "Jim Red",
    age: 32,
    address: "London No. 2 Lake Park"
  }
];

class App extends React.Component {
  state = {
    sRT: ""
  };

  getColumnSearchProps = dataIndex => ({
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters
    }) => (
      <div style={{ padding: 8 }}>
        <Input
          placeholder={`Search ${dataIndex}`}
          //value={selectedKeys[0]}
          onChange={e =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
          style={{ width: 188, marginBottom: 8, display: "block" }}
        />
      </div>
    ),
    filterIcon: filtered => (
      <Icon type="search" style={{ color: filtered ? "#1890ff" : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex]
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => this.searchInput.select());
      }
    },
    render: text => (
      <Highlighter
        highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
        searchWords={[this.state.sRT]}
        autoEscape
        textToHighlight={text.toString()}
      />
    )
  });

  handleSearch = (selectedKeys, confirm) => {
    confirm();
    this.setState({ sRT: selectedKeys[0] });
  };

  handleReset = clearFilters => {
    clearFilters();
    this.setState({ sRT: "" });
  };

  render() {
    const columns = [
      {
        title: "Name",
        dataIndex: "name",
        key: "name",
        width: "30%",
        ...this.getColumnSearchProps("name")
      },
      {
        title: "Age",
        dataIndex: "age",
        key: "age",
        width: "20%",
        ...this.getColumnSearchProps("age")
      },
      {
        title: "Address",
        dataIndex: "address",
        key: "address",
        ...this.getColumnSearchProps("address")
      }
    ];
    return (
      <div>
        <Input type="text" placeholder="search" />
        <Table columns={columns} dataSource={data} />;
        <br />
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

【问题讨论】:

  • “为了方便参考,我也把演示代码贴在这里。” 是的!总是。谢谢!
  • (顺便说一句,您也可以使用 Stack Snippets([&lt;&gt;] 工具栏按钮)创建可运行版本。Stack Snippets 支持 React,包括 JSX;here's how to do one。)

标签: javascript reactjs antd


【解决方案1】:

你需要添加额外的状态:

  1. 过滤数据的状态dataSource
  2. Input 值的状态:nameSearch
state = {
  sRT: "",
  dataSource: data,
  nameSearch: ""
};

进行过滤时将dataSource 提供给Table 组件:

// Filtered data
<Table columns={columns} dataSource={this.state.dataSource} />

剩下要做的是添加过滤器组件,here is an example 用于三个基本的antd 组件:

  • AutoComplete
  • Input.Search
  • AutoCompleteInput.Search
<>
  <Row>
    <Table columns={columns} dataSource={this.state.dataSource} />
  </Row>
  <Row type="flex" gutter={10} style={{ marginBottom: 10 }}>
    <Col>
      <Typography>Name Auto Complete</Typography>
    </Col>
    <Col>
      <AutoComplete
        dataSource={data.map(person => person.name)}
        onChange={nameSearch =>
          this.setState({
            dataSource: data.filter(person => person.name.includes(nameSearch))
          })
        }
        allowClear
      />
    </Col>
  </Row>
  <Row type="flex" gutter={10} style={{ marginBottom: 10 }}>
    <Col>
      <Typography>Name Search</Typography>
    </Col>
    <Col>
      <Input.Search
        allowClear
        onSearch={nameSearch =>
          this.setState({
            dataSource: data.filter(person => person.name.includes(nameSearch))
          })
        }
      />
    </Col>
  </Row>
  <Row type="flex" gutter={10}>
    <Col>
      <Typography>Auto Complete Search</Typography>
    </Col>
    <Col>
      <AutoComplete dataSource={data.map(person => person.name)}>
        <Input.Search
          allowClear
          onSearch={nameSearch =>
            this.setState({
              dataSource: data.filter(person =>
                person.name.includes(nameSearch)
              )
            })
          }
        />
      </AutoComplete>
    </Col>
  </Row>
</>;

【讨论】:

  • 我无法理解这个!对于每次搜索,您都使用this.setState({dataSource: data.filter(person =&gt;person.name.includes(nameSearch)) 更改状态变量dataSource。删除搜索文本后,数据如何再次出现?该表从 dataSource 派生其值,您在搜索时更改它。
  • 因为清除输入时,值等于''(一个空字符串),并且每个字符串都包含空字符串。
  • 如果我的表源自data,其数据源为leftTableDataSource(其中leftTableDataSource 源自数据)而我只想搜索leftTableDataSource,该怎么办?
  • 您的问题超出范围...请发布另一个...我不知道您指的是什么data,它是如何“派生”的,“leftTable”是如何构成的等等...
  • 有没有办法只过滤自动完成输入中的相关文本?例如,如果我输入“red”,除了包含“red”的条目之外的所有其他条目都保留在自动完成框中?
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2019-01-10
  • 2017-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多