Table 手动输入实现多条件筛选
要是不想看改HOOK的部分,可以先看官方的例子,然后跳到条件筛选关键语句
官网例子改HOOK版样例
官方版本
首先给出官网找到的例子作为参考
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Input, Button, Space } from 'antd';
import Highlighter from 'react-highlight-words';
import { SearchOutlined } from '@ant-design/icons';
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 = {
searchText: '',
searchedColumn: '',
};
getColumnSearchProps = dataIndex => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
ref={node => {
this.searchInput = node;
}}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Space>
<Button
type="primary"
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({ closeDropdown: false });
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
}}
>
Filter
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}
},
render: text =>
this.state.searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[this.state.searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
text
),
});
handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
handleReset = clearFilters => {
clearFilters();
this.setState({ searchText: '' });
};
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 <Table columns={columns} dataSource={data} />;
}
}
ReactDOM.render(<App />, document.getElementById('container'));
HOOK版本
稍微照HOOK改一下,因为我用的HOOK
import React, { useRef, useState } from 'react';
import { Table, Input, Button, Space } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
function multiFilterTable(props) {
const [state, setState] = useState({
searchText: '',
searchedColumn: '',
})
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',
},
];
//因为没有找到this.searchInput的代替
//就用let好了
let searchInput
const getColumnSearchProps = dataIndex => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
ref={node => {
searchInput = node;
}}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({ closeDropdown: false });
setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
}}
>
Filter
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => searchInput.select(), 100);
}
},
render: text =>
state.searchedColumn === dataIndex ? (
//本地没有'react-highlight-words',凑合一下
<p style={{ backgroundColor: '#ffc069', padding: 0 }}>{text}</p>
) : (
text
),
});
let handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
let handleReset = clearFilters => {
clearFilters();
setState({ searchText: '' });
};
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: '30%',
...getColumnSearchProps('name'),
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: '20%',
...getColumnSearchProps('age'),
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
...getColumnSearchProps('address'),
},
];
return <Table columns={columns} dataSource={data} />;
}
export default multiFilterTable;
Hooks版本就有了
条件筛选关键语句
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
可以看到判断的是该条record是否包含value,即Input内的值
存在的返回true,不存在返回 false
然后再根据对应的数据更新背景颜色
所以如何做到多条件筛选呢?
更改为多条件筛选
其实也很简单,全输进去拆开来找就行
我这里采用“;”作为分割每个筛选条件的分割符
但同时也要记得保证原来的逻辑
onFilter: (value, record) => {
if(!record[dataIndex]) return ''
let tag=false
let tempdata=value.split(';')
//只要有一个存在包含的情况,tag 即为true
tempdata.forEach((item)=>{
record[dataIndex].toString().toLowerCase().includes(item.toLowerCase())?tag=true:null
})
return tag
// return record[dataIndex]
// ? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
// : ''
}
当然这种写法还有优化的空间
仅供参考
如果帮助到你,能点个赞吗?