From a6d2de1a7b62d2ff1392317a8ab2cedfc9d34c17 Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 14 Nov 2016 17:53:02 +0800 Subject: [PATCH] controlled filterDropdown props, close #3003 --- components/table/demo/ajax.md | 2 +- components/table/demo/custom-filter-panel.md | 125 +++++++++++++++++++ components/table/filterDropdown.tsx | 40 ++++-- components/table/index.en-US.md | 4 +- components/table/index.zh-CN.md | 4 +- 5 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 components/table/demo/custom-filter-panel.md diff --git a/components/table/demo/ajax.md b/components/table/demo/ajax.md index 413419bdbe..fe4cf61a3c 100644 --- a/components/table/demo/ajax.md +++ b/components/table/demo/ajax.md @@ -1,5 +1,5 @@ --- -order: 7 +order: 8 title: en-US: Ajax zh-CN: 远程加载数据 diff --git a/components/table/demo/custom-filter-panel.md b/components/table/demo/custom-filter-panel.md new file mode 100644 index 0000000000..33d92d9936 --- /dev/null +++ b/components/table/demo/custom-filter-panel.md @@ -0,0 +1,125 @@ +--- +order: 7 +title: + en-US: Customized filter panel + zh-CN: 自定义筛选菜单 +--- + +## zh-CN + +通过 `filterDropdown`、`filterDropdownVisible` 和 `filterDropdownVisibleChange` 定义自定义的列筛选功能,并实现一个搜索列的示例。 + +## en-US + +Implement a customized column search example via `filterDropdown`, `filterDropdownVisible` and `filterDropdownVisibleChange`. + +````jsx +import { Table, Input, Button } from 'antd'; + +const data = [{ + key: '1', + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park', +}, { + key: '2', + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park', +}, { + key: '3', + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park', +}, { + key: '4', + name: 'Jim Red', + age: 32, + address: 'London No. 2 Lake Park', +}]; + +const App = React.createClass({ + getInitialState() { + return { + filterDropdownVisible: false, + data, + searchText: '', + }; + }, + onInputChange(e) { + this.setState({ searchText: e.target.value }); + }, + onSearch() { + const { searchText } = this.state; + const reg = new RegExp(searchText, 'gi'); + this.setState({ + filterDropdownVisible: false, + data: data.map((record) => { + const match = record.name.match(reg); + if (!match) { + return null; + } + return { + ...record, + name: ( + + {record.name.split(reg).map((text, i) => ( + i > 0 ? [{match[0]}, text] : text + ))} + + ), + }; + }).filter(record => !!record), + }); + }, + render() { + const columns = [{ + title: 'Name', + dataIndex: 'name', + key: 'name', + filterDropdown: ( +
+ + +
+ ), + filterDropdownVisible: this.state.filterDropdownVisible, + onFilterDropdownVisibleChange: visible => this.setState({ filterDropdownVisible: visible }), + }, { + title: 'Age', + dataIndex: 'age', + key: 'age', + }, { + title: 'Address', + dataIndex: 'address', + key: 'address', + }]; + return ; + }, +}); + +ReactDOM.render(, mountNode); +```` + +````css +.custom-filter-dropdown { + padding: 8px; + border-radius: 6px; + background: #fff; + box-shadow: 0 1px 6px rgba(0, 0, 0, .2); +} + +.custom-filter-dropdown input { + width: 130px; + margin-right: 8px; +} + +.highlight { + color: #f50; +} +```` diff --git a/components/table/filterDropdown.tsx b/components/table/filterDropdown.tsx index 2b6813499b..32f5e36a6a 100755 --- a/components/table/filterDropdown.tsx +++ b/components/table/filterDropdown.tsx @@ -12,7 +12,9 @@ export interface FilterMenuProps { column: { filterMultiple?: boolean, filterDropdown?: React.ReactNode, - filters?: string[] + filters?: string[], + filterDropdownVisible?: boolean, + onFilterDropdownVisibleChange?: (visible: boolean) => any, }; confirmFilter: (column: Object, selectedKeys: string[]) => any; prefixCls: string; @@ -22,7 +24,7 @@ export interface FilterMenuProps { export default class FilterMenu extends React.Component { static defaultProps = { handleFilter() {}, - column: null, + column: {}, }; constructor(props) { @@ -36,15 +38,35 @@ export default class FilterMenu extends React.Component { } componentWillReceiveProps(nextProps) { - this.setState({ - selectedKeys: nextProps.selectedKeys, - }); + const { column } = nextProps; + let newState; + if ('selectedKeys' in nextProps) { + newState = newState || {}; + newState.selectedKeys = nextProps.selectedKeys; + } + if ('filterDropdownVisible' in column) { + newState = newState || {}; + newState.visible = column.filterDropdownVisible; + } + if (newState) { + this.setState(newState); + } } setSelectedKeys = ({ selectedKeys }) => { this.setState({ selectedKeys }); } + setVisible(visible) { + const { column } = this.props; + if (!('filterDropdownVisible' in column)) { + this.setState({ visible }); + } + if (column.onFilterDropdownVisibleChange) { + column.onFilterDropdownVisibleChange(visible); + } + } + handleClearFilters = () => { this.setState({ selectedKeys: [], @@ -52,16 +74,12 @@ export default class FilterMenu extends React.Component { } handleConfirm = () => { - this.setState({ - visible: false, - }); + this.setVisible(false); this.confirmFilter(); } onVisibleChange = (visible) => { - this.setState({ - visible, - }); + this.setVisible(visible); if (!visible) { this.confirmFilter(); } diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index 7d84d059d8..e69bee8005 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -90,12 +90,14 @@ One of Property `columns` for descriping column. | onFilter | callback that is called when when click confirm filter button | Function | - | | filterMultiple | whether to select multiple filtered item | Boolean | true | | filterDropdown | customized filter overlay | React.Element | - | +| filterDropdownVisible | whether filterDropdown is visible | Boolean | - | +| onFilterDropdownVisibleChange | called when filterDropdownVisible is changed | function(visible) {} | - | +| filteredValue | controlled filtered value | Array | - | | sorter | sort function for local sort. If you need sort buttons only, set it `true` | Function or Boolean | - | | colSpan | span of this column's title | Number | | | width | width of this column | String or Number | - | | className | className of this column | String | - | | fixed | set column to be fixed: `true`(same as left) `'left'` `'right'` | Boolean or String | false | -| filteredValue | controlled filtered value | Array | - | | sortOrder | controlled sorted value: `'ascend'` `'descend'` `false` | Boolean or String | - | ### rowSelection diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 00816fadfd..650f2f378e 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -91,12 +91,14 @@ const columns = [{ | onFilter | 本地模式下,确定筛选的运行函数 | Function | - | | filterMultiple | 是否多选 | Boolean | true | | filterDropdown | 可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互 | React.Element | - | +| filterDropdownVisible | 用于控制自定义筛选菜单是否可见 | Boolean | - | +| onFilterDropdownVisibleChange | 自定义筛选菜单可见变化时调用 | function(visible) {} | - | +| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | Array | - | | sorter | 排序函数,本地排序使用一个函数,需要服务端排序可设为 true | Function or Boolean | - | | colSpan | 表头列合并,设置为 0 时,不渲染 | Number | | | width | 列宽度 | String or Number | - | | className | 列的 className | String | - | | fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | Boolean or String | false | -| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | Array | - | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | Boolean or String | - | ### rowSelection