I’m working on antd table, and implemented search function for each column and it is working properly, But only problem is my search bar is shown as a popup(dropdown) and it covers the data of first row as shown in the screenshot.
Reference: https://ant.design/components/table/#components-table-demo-custom-filter-panel
I want to move the search bar in the column heading as shown below.
Following is my code
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 = {
{
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'),
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
},
];
return <Table columns = {
columns
}
dataSource = {
data
}
/>;
}
}
ReactDOM.render( < App / > , document.getElementById('container'));
>Solution :
Check the following code snippet to solve your problem, It shows how to add search bar in column heading. It will add search bar to the right of the filter icon.
const [filterval, setfilterval] = useState([]);
const columns = [
{
title: 'User name',
dataIndex: 'username',
key: 'username',
filteredValue: filterval,
width: 600,
filterDropdown: ({
setSelectedKeys,
selectedKeys,
}) => {
return (<></>);
},
filterIcon: () => {
return <><Input
autoFocus
allowClear
placeholder="Search"
value={filterval}
onChange={(e) => { setfilterval(e.target.value ? [e.target.value] : []) }}
style={{ width: '190px', height: '30px' }}
size="middle"
></Input>
<SearchOutlined style={{marginLeft: '5px' }} />
</>;
},
onFilter: (value, record) => {
return record.username.toLowerCase().includes(value.toLowerCase());
},
},
}
