How to do column level search in ant-design using function component? - reactjs

I'm using function component and to draw the table I'm using ant-design. Now I want to do column search for each column present in table
I tried this
https://ant.design/components/table/
It's a class component I got bit confused. Can anyone suggest how to search column level search in ant design table using function component?
Thanks

just to complement the previous answer: searchInput is a resp, in class component it is automatic but in function you have to do the following:
....
const searchInput = useRef(null);
....
<Input
ref={searchInput}
....
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => searchInput && searchInput.current && searchInput.current.select())
}
}
.....

It should be this way, sorry if i forgot to replace a this. I followed the antd table API here https://ant.design/components/table/#components-table-demo-custom-filter-panel
const { Table, Input, Button, Space } = antd;
import Highlighter from 'react-highlight-words';
const { SearchOutlined } = 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',
},
];
const App = () => {
const [state, setState] = useState({searchText:'', searchedColumn:''})
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
const handleReset = clearFilters => {
clearFilters();
setState({ searchText: '' });
};
const 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={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ 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 ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[state.searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
text
),
});
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'),
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
},
];
return <Table columns={columns} dataSource={data} />;
}
ReactDOM.render(<App />, mountNode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Related

How to triger a filter on a antd table with searchParams

I am using an antd table with a customized filter and I am trying to implement a new feature using URL search params to save time when sharing filtered results with colleagues, the idea is to share links.
The search params are being set on the URL after a filter, also I created a conditional in componentDidMount to check and get the search params and set the keyword on the in the component's state which I believe is what is required to trigger the filter on the table.
When pasting the URL on a new tab/browser, the component mounts with the desire state value but the filter doesn't kicks in.
Does anyone knows how to do it ? Any help is appreciated
Demo_In_CodeSandbox_here - takes a minute to load the table
I pasted the code below too.
import React from "react";
import "antd/dist/antd.css";
import "./styles.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) => {
const params = new URLSearchParams(window.location.search);
params.set(dataIndex, selectedKeys[0]);
window.history.replaceState(
{},
"",
`${window.location.pathname}?${params}`
);
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex
});
};
handleReset = (clearFilters) => {
clearFilters();
this.setState({ searchText: "" });
};
componentDidMount() {
if (window.location.search) {
let arrParams = null;
const getUrl = new URL(window.location.href);
let params = new URLSearchParams(getUrl.search);
for (let p of params) {
arrParams = p;
}
console.log(arrParams);
const [dataIndex, selectedKeys] = arrParams;
this.setState({
searchText: selectedKeys,
searchedColumn: dataIndex
});
}
}
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} />;
}
}
export default App;

Table Filter with DatePicker using antd

Following is the code for Ant design table with filtering the object using the DatePicker but not able to filter Out and Reset and Filter button also not Working Can anyone help me to solve this problem.
CodeSandbox editor Link : https://codesandbox.io/s/customized-filter-panel-antd-4-18-4-forked-lzuru?file=/index.js
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, DatePicker, Button, Space } from "antd";
import Highlighter from "react-highlight-words";
import { SearchOutlined } from "#ant-design/icons";
const data = [
{
key: "1",
name: "John Brown",
date: "2022-01-27T00:00:00Z",
address: "New York No. 1 Lake Park"
},
{
key: "2",
name: "Joe Black",
date: "2022-01-27T00:00:00Z",
address: "London No. 1 Lake Park"
},
{
key: "3",
name: "Jim Green",
date: "2022-01-25T00:00:00Z",
address: "Sidney No. 1 Lake Park"
},
{
key: "4",
name: "Jim Red",
age: "2022-01-22T00:00:00Z",
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 }}>
<Space>
<DatePicker
// format={"DD-MM-YY"}
onChange={(e) => {
setSelectedKeys([e.format("YYYY-MM-DDT00:00:00Z")]);
}}
allowClear={false}
/>
</Space>
<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) =>{
return(
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) => {
console.log(selectedKeys, confirm, dataIndex);
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex
});
};
handleReset = (clearFilters) => {
clearFilters();
// console.log(this.state.searchText);
this.setState({ searchText: "" });
};
render() {
console.log(this.state.searchText);
const columns = [
{
title: "Name",
dataIndex: "name",
key: "name",
width: "30%"
},
{
title: "Date",
dataIndex: "date",
key: "date",
width: "20%",
...this.getColumnSearchProps("date")
}
];
return <Table columns={columns} dataSource={data} />;
}
}
You can use moment to compare the dates and filter
getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters
}) => (
<div style={{ padding: 8 }}>
<Space>
<DatePicker
// format={"DD-MM-YY"}
onChange={(e) => {
setSelectedKeys([e]);
}}
allowClear={true}
/>
</Space>
<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) => {
return (
moment(record[dataIndex]).format("DD-MM-YYYY") ===
value.format("DD-MM-YYYY")
);
},
First of all it is a bad idea to compare your dates as strings. or your use case where you only want to compare dates without time, you can compare dates using isSame().
To reset the filter state, you can use a controlled state to clear your filters as shown in the antd clear filter example

React Ant deisgn 4 Table search input cursor going to center

Im using my react project for ant design 4 table, when I search the table data , input cursor going to center and data not searching any solution for this, please look ta my following link and just copy paste address then search you can see the conflict.
stakblitz
code here
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>
</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} />;
}
}

And Design Table TypeScript getColumnSearchProps example

i'm using the following ant component : https://ant.design/components/table/
and i'm really struggling to add the following search option in my table :
here's the table i've created so far :
i'm pretty new to both React and Typescript , since the project is not in js but in typescript i cannot get my code to work properly looking at ant documentation ; i've turned my component to a functional component as i'm gonna be using hooks and added some code to get out most of the compiler errors (type declaration for ts) , still have some syntax errors :
heres my code:
import React, { Component, useState } from 'react';
import {connect} from "react-redux";
// #ts-ignore
import Highlighter from 'react-highlight-words';
//**External Libraries */
//REACT MOSAIC
import {ExpandButton, MosaicWindow, RemoveButton} from "react-mosaic-component";
import {MosaicBranch} from "react-mosaic-component/src/types";
//BLUEPRINTJS
import {InputGroup} from "#blueprintjs/core";
//ANTDESIGN
import { Table , Button ,Tag , Input , Space} from "antd";
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
import {CaretRightOutlined , SearchOutlined} from '#ant-design/icons';
//STYLES
import './styles.css'
//API
import {useGetAllUtenti} from '../../../api/index';
import { Utente } from '../../../api/types';
const UserSummaryWindow: React.FC<any> = (props) => {
//HOOKS STATE FOR TABLE SEARCH
const [searchText , setSearchText] = useState('');
const [searchedColumn , setSearchedColumn] = useState('');
const {path} = props;
const dataSource: Object | any = useGetAllUtenti().data;
const ruoli: any = [
{
text: 'User',
value: 'user',
},
{
text: 'Administrator',
value: 'administrator',
},
{
text: 'NumeroVerde',
value: 'numeroVerde',
},
]
const stati: any = [
{
text: 'Attivo',
value: 1,
},
{
text: 'Non Attivo',
value: 0,
}
]
const columns: any = [
{
title: 'Nome',
dataIndex: 'nome',
key: 'nome',
defaultSortOrder: 'descend',
sorter: (a:any, b:any) => { return a.nome.localeCompare(b.nome)},
},
{
title: 'Cognome',
dataIndex: 'cognome',
key: 'cognome',
sorter: (a:any, b:any) => { return a.cognome.localeCompare(b.cognome)},
},
{
title: 'Ruolo',
dataIndex: 'ruolo',
key: 'ruolo',
filters: ruoli,
onFilter: (value:any, record:any) => record.ruolo.indexOf(value) === 0,
sorter: (a:any, b:any) => { return a.ruolo.localeCompare(b.ruolo)},
render: (text: string) => (
<>
{
<Tag color={renderTagColor(text)}>
{text.toUpperCase()}
</Tag>
}
</>)
},
{
title: 'Gestore',
dataIndex: 'gestore',
key: 'gestore',
sorter: (a:any, b:any) => { return a.gestore.localeCompare(b.gestore)},
},
{
title: 'Username',
dataIndex: 'username',
key: 'username',
sorter: (a:any, b:any) => { return a.username.localeCompare(b.username)},
},
// {
// title: 'Password',
// dataIndex: 'password',
// key: 'password',
// },
// {
// title: 'IDEnte',
// dataIndex: 'idEnte',
// key: 'idEnte',
// },
{
title: 'Tipo',
dataIndex: 'tipo',
key: 'tipo',
sorter: (a:any, b:any) => a.tipo - b.tipo,
},
{
title: 'Stato',
dataIndex: 'stato',
key: 'stato',
filters: stati,
onFilter: (value:any, record:any) => record.stato.indexOf(value) === 0,
sorter: (a:any, b:any) => a.stato - b.stato,
render :(stato: number) => (
<>
{
(stato == 1) ?
(
<Tag color="#00cc00">
Attivo
</Tag>
) :
(
<Tag color="#ff0000">
Non Attivo
</Tag>
)
}
</>)
},
{
title: 'Ultimo aggiornamento password',
dataIndex: 'ultimoAggiornamentoPassword',
key: 'ultimoAggiornamentoPassword',
sorter: (a:any, b:any) => a.ultimoAggiornamentoPassword.localeCompare(b.ultimoAggiornamentoPassword)
},
{
title: '',
dataIndex: 'idUtente',
key: 'idUtente',
render: () => (
//da inserire link per andare al dettaglio / modifica utente
<Button type="primary"><CaretRightOutlined /></Button>
),
},
]
const toolbarControls = React.Children.toArray([
<ExpandButton/>,
<RemoveButton/>
]);
function renderTagColor(text:string): string {
switch(text) {
case 'user':
return 'gold';
case 'administrator':
return 'red';
case 'numeroVerde':
return 'green';
default:
return '';
}
}
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={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined 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:string) =>
searchText === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text.toString()}
/>
) : (
text
),
});
function handleSearch (selectedKeys:any, confirm:any, dataIndex:any) {
confirm();
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
};
function handleReset (clearFilters:any) {
clearFilters();
setSearchText('');
};
return (
<MosaicWindow<string>
title="Riepilogo Utenti"
path={path}
toolbarControls={toolbarControls}
>
<Table
dataSource={dataSource}
columns={columns}
bordered={true}
//pagination={{ pageSize:3,position: ['bottomCenter'] }}
pagination={{position: ['bottomCenter'] }}
rowKey={'idUtente'}
//stile per righe striped
rowClassName={(record, index) => index % 2 === 0 ? 'table-row-light' : 'table-row-dark'}
/>
</MosaicWindow>
);
};
export default UserSummaryWindow;
The part which is giving me headeache is (need to convert it to typescript [strict option in config file is enabled]):
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={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined 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:string) =>
searchText === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text.toString()}
/>
) : (
text
),
});
I'm not here asking you to correct my code , just wanted to know if anyone could share a typescript implementation of that getColumnSearchProps function , or an example of the table component from ant design with typescript code..
Sorry for such a late reply, i was having the same problem.
I found the solution on a github repo someone made. i really wonder why the antd devs don't support typescript in these days.
anyways, here is the repo.
https://github.com/freewind-demos/typescript-react-antd-table-search-column-demo
Basically All the hardwork of moving the old JS code to typescript is done, although there are some linting errors here and there.
I hope anyone who comes looking for this answer really questions their decision to use antd instead of react-table or material-design.
Same answer as Lav Hinsu, but I'll paste the full code here, just in case that link dies.
import "antd/dist/antd.css";
import React from "react";
import ReactDOM from "react-dom";
import { SearchOutlined } from "#ant-design/icons";
import { Table, Button, Input } from "antd";
import { ColumnType } from "antd/lib/table";
function tableColumnTextFilterConfig<T>(): ColumnType<T> {
const searchInputHolder: { current: Input | null } = { current: null };
return {
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Input
ref={(node) => {
searchInputHolder.current = node;
}}
placeholder="Search"
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(e.target.value ? [e.target.value] : [])
}
onPressEnter={() => confirm()}
style={{ width: 188, marginBottom: 8, display: "block" }}
/>
<Button
type="primary"
onClick={() => confirm()}
icon={<SearchOutlined />}
size="small"
style={{ width: 90, marginRight: 8 }}
>
Search
</Button>
<Button size="small" style={{ width: 90 }} onClick={clearFilters}>
Reset
</Button>
</div>
),
filterIcon: (filtered) => (
<SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
),
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => searchInputHolder.current?.select());
}
},
};
}
type Data = {
key: string;
name: string;
};
const data: Data[] = [
{
key: "1",
name: "John Brown",
},
{
key: "2",
name: "Jim Green",
},
{
key: "3",
name: "Joe Black",
},
];
function Hello() {
return (
<div>
<Table
columns={[
{
title: "Name",
dataIndex: "name",
render: (text: string) => text,
...tableColumnTextFilterConfig<Data>(),
onFilter: (value, record) => {
return record.name
.toString()
.toLowerCase()
.includes(value.toString().toLowerCase());
},
},
]}
dataSource={data}
/>
</div>
);
}
ReactDOM.render(<Hello />, document.body);
In short, you can just extract the tableColumnTextFilterConfig function and implement the onFilter property on the desired column.

Filter antd Table With datePicker in react

Following is the code for Ant design table with filtering the object using the input field but i want it to transform it for antd datepicker field instead of input field but not getting how to tranform it.
const data = [
{
key: '1',
date: '2020-04-01',
},
{
key: '2',
date: '2020-04-04',
},
{
key: '3',
date: '2020-04-03',
},
{
key: '4',
date: '2020-04-02',
},
];
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' }}
/>
<Button
type="primary"
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90, marginRight: 8 }}
>
Search
</Button>
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
</div>
),
filterIcon: filtered => <SearchOutlined 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 =>
this.state.searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[this.state.searchText]}
autoEscape
textToHighlight={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: 'Date',
dataIndex: 'name',
key: 'name',
width: '30%',
...this.getColumnSearchProps('name'),
},
];
return <Table columns={columns} dataSource={data} />;
}
}
ReactDOM.render(<App />, mountNode);
Following is the code for Ant design table with filtering the object using the input field but i want it to transform it for antd datepicker field instead of input field but not getting how to tranform it.
You can use something like this to display a datePicker instead of a searchInput.
<div style={{ padding, width }}>
<DatePicker.RangePicker
autoFocus={autoFocus}
onChange={handleChange}
placeholder={placeholder}
value={value}
format={format}
style={{ marginBottom: 8 }}
/>
<Button
type="primary"
role="search"
onClick={handleSearch}
style={{ width: btnWidth }}
icon={<SearchOutlined />}
size="small"
>
{label[0]}
</Button>
<Button
role="reset"
style={{ width: btnWidth, marginLeft }}
onClick={handleClear}
size="small"
>
{label[1]}
</Button>
</div>
Old question but hope can help someone in the future!
That code is the one from the table search filter but you should create something like this:
// you need momentjs
import moment from "moment";
// the table data
import data from "../fakeData.js";
class myTable extends Component {
constructor(props) {
super(props);
state = {
data: data,
filteredInfo: null,
searchTimeText: null,
searchedTimeColumn: null,
};
};
clearFilters = () => {
this.setState(
{ filteredInfo: null }
);
};
handleTimeRangeSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
this.setState({
searchTimeText: selectedKeys[0],
searchedTimeColumn: dataIndex,
});
};
handleTimeRangeReset = clearFilters => {
clearFilters();
this.setState({
searchTimeRange: null,
searchTimeRangeColumn: null,
});
};
getColumnTimeProps = dataIndex => ({
filterDropdown: ({setSelectedKeys, selectedKeys, confirm, clearFilters}) => (
<div style={{ padding: 8 }}>
<DatePicker.RangePicker
onChange={e => {
setSelectedKeys(e.length ? [e] : [])
}}
placeholder={["Start", "End"]}
value={selectedKeys[0]}
format="YYYY-MM-DD HH:mm:ss"
/>
<Button
type="primary"
role="search"
onClick={() => {
this.handleTimeRangeSearch(selectedKeys, confirm, dataIndex)
}}
style={{ width: 90, marginRight: 8 }}
icon={<SearchOutlined />}
size="small"
>
Search
</Button>
<Button
role="reset"
style={{ width: 90 }}
onClick={() => this.handleTimeRangeReset(clearFilters)}
size="small"
>
Reset
</Button>
</div>
),
filterIcon: filtered => (
<FieldTimeOutlined type="search" style={{ color: filtered ? "#1890ff" : undefined }} />
),
onFilter: (value, record) => record[dataIndex] ? moment(record[dataIndex]).isBetween(moment(value[0]), moment(value[1])) : "",
render: text => text
});
render() {
let {
data,
filteredInfo
} = this.state;
// table columns config
const columns = [
//...
{
title: 'Date',
dataIndex: 'date',
key: 'date',
sorter: (a, b) => a.date > b.date,
sortOrder: sortedInfo.columnKey === 'date' && sortedInfo.order,
...this.getColumnTimeProps('date'),
filteredValue: filteredInfo.date || null,
},
//...
];
// the table
return (<Table dataSource={data} columns={columns} />)
);
}

Resources