From 04c21cb63daa84c467e9e71270b8d221565ec850 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sun, 24 Jun 2018 15:03:46 +0800 Subject: [PATCH] implement custom filter --- .../react-bootstrap-table2-filter/index.js | 7 ++ .../src/wrapper.js | 8 +++ .../src/bootstrap-table.js | 4 +- .../react-bootstrap-table2/src/header-cell.js | 14 +++- packages/react-bootstrap-table2/src/header.js | 7 +- .../test/header-cell.test.js | 70 +++++++++++++++++++ 6 files changed, 104 insertions(+), 6 deletions(-) diff --git a/packages/react-bootstrap-table2-filter/index.js b/packages/react-bootstrap-table2-filter/index.js index 0f17bd3..fe60268 100644 --- a/packages/react-bootstrap-table2-filter/index.js +++ b/packages/react-bootstrap-table2-filter/index.js @@ -4,12 +4,15 @@ import NumberFilter from './src/components/number'; import DateFilter from './src/components/date'; import wrapperFactory from './src/wrapper'; import * as Comparison from './src/comparison'; +import { FILTER_TYPE } from './src/const'; export default (options = {}) => ({ wrapperFactory, options }); +export const FILTER_TYPES = FILTER_TYPE; + export const Comparator = Comparison; export const textFilter = (props = {}) => ({ @@ -31,3 +34,7 @@ export const dateFilter = (props = {}) => ({ Filter: DateFilter, props }); + +export const customFilter = (props = {}) => ({ + props +}); diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js index 33867fd..c2b24e8 100644 --- a/packages/react-bootstrap-table2-filter/src/wrapper.js +++ b/packages/react-bootstrap-table2-filter/src/wrapper.js @@ -20,6 +20,7 @@ export default (Base, { super(props); this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false }; this.onFilter = this.onFilter.bind(this); + this.onExternalFilter = this.onExternalFilter.bind(this); } componentWillReceiveProps({ isDataChanged, store, columns }) { @@ -78,12 +79,19 @@ export default (Base, { }; } + onExternalFilter(column, filterType) { + return (value) => { + this.onFilter(column, filterType)(value); + }; + } + render() { return ( ); diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index 723f5bd..fe6865c 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -90,6 +90,7 @@ class BootstrapTable extends PropsBaseResolver(Component) { sortOrder={ store.sortOrder } onSort={ this.props.onSort } onFilter={ this.props.onFilter } + onExternalFilter={ this.props.onExternalFilter } selectRow={ headerCellSelectionInfo } /> { sorting, sortOrder, isLastSorting, - onFilter + onFilter, + onExternalFilter } = props; const { text, sort, filter, + filterRenderer, headerTitle, headerAlign, headerFormatter, @@ -89,7 +91,11 @@ const HeaderCell = (props) => { if (cellClasses) cellAttrs.className = cs(cellAttrs.className, cellClasses); if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle; - if (filter) { + + if (filterRenderer) { + const onCustomFilter = onExternalFilter(column, filter.props.type); + filterElm = filterRenderer(onCustomFilter, column); + } else if (filter) { filterElm = ; } @@ -136,6 +142,7 @@ HeaderCell.propTypes = { editorRenderer: PropTypes.func, validator: PropTypes.func, filter: PropTypes.object, + filterRenderer: PropTypes.func, filterValue: PropTypes.func }).isRequired, index: PropTypes.number.isRequired, @@ -143,7 +150,8 @@ HeaderCell.propTypes = { sorting: PropTypes.bool, sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC]), isLastSorting: PropTypes.bool, - onFilter: PropTypes.func + onFilter: PropTypes.func, + onExternalFilter: PropTypes.func }; export default HeaderCell; diff --git a/packages/react-bootstrap-table2/src/header.js b/packages/react-bootstrap-table2/src/header.js index 38b8c3a..5fd7e57 100644 --- a/packages/react-bootstrap-table2/src/header.js +++ b/packages/react-bootstrap-table2/src/header.js @@ -15,7 +15,8 @@ const Header = (props) => { onFilter, sortField, sortOrder, - selectRow + selectRow, + onExternalFilter } = props; return ( @@ -39,6 +40,7 @@ const Header = (props) => { onSort={ onSort } sorting={ currSort } onFilter={ onFilter } + onExternalFilter={ onExternalFilter } sortOrder={ sortOrder } isLastSorting={ isLastSorting } />); @@ -57,7 +59,8 @@ Header.propTypes = { onFilter: PropTypes.func, sortField: PropTypes.string, sortOrder: PropTypes.string, - selectRow: PropTypes.object + selectRow: PropTypes.object, + onExternalFilter: PropTypes.func }; export default Header; diff --git a/packages/react-bootstrap-table2/test/header-cell.test.js b/packages/react-bootstrap-table2/test/header-cell.test.js index 535d222..6814135 100644 --- a/packages/react-bootstrap-table2/test/header-cell.test.js +++ b/packages/react-bootstrap-table2/test/header-cell.test.js @@ -669,4 +669,74 @@ describe('HeaderCell', () => { }); }); }); + + describe('when column.filter is defined', () => { + const onFilter = jest.fn(); + const filterProps = { a: 123 }; + const Filter = () =>
test
; + let column; + + beforeEach(() => { + onFilter.mockClear(); + column = { + dataField: 'id', + text: 'ID', + filter: { + props: filterProps, + Filter + } + }; + wrapper = shallow(); + }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.find('th').length).toBe(1); + }); + + it('should render filter correctly', () => { + expect(wrapper.find(Filter).length).toBe(1); + expect(wrapper.find(Filter).props()).toEqual({ + column, + onFilter, + ...filterProps + }); + }); + }); + + describe('when column.filter and column.filterRenderer is defined', () => { + const onExternalFilter = jest.fn(); + const filterProps = { a: 123 }; + const Filter = () =>
test
; + const filterRenderer = jest.fn().mockReturnValue(); + let column; + + beforeEach(() => { + onExternalFilter.mockClear(); + filterRenderer.mockClear(); + column = { + dataField: 'id', + text: 'ID', + filter: { + props: filterProps + }, + filterRenderer + }; + wrapper = shallow( + ); + }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.find('th').length).toBe(1); + }); + + it('should render filter correctly', () => { + expect(wrapper.find(Filter).length).toBe(1); + }); + + it('should call filterRenderer function correctly', () => { + expect(filterRenderer).toHaveBeenCalledTimes(1); + }); + }); });