mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-04-04 20:04:27 +00:00
implement custom filter
This commit is contained in:
@@ -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
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
<Base
|
||||
{ ...this.props }
|
||||
data={ this.props.store.data }
|
||||
onFilter={ this.onFilter }
|
||||
onExternalFilter={ this.onExternalFilter }
|
||||
isDataChanged={ this.state.isDataChanged }
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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 }
|
||||
/>
|
||||
<Body
|
||||
@@ -162,7 +163,8 @@ BootstrapTable.propTypes = {
|
||||
overlay: PropTypes.func,
|
||||
onTableChange: PropTypes.func,
|
||||
onSort: PropTypes.func,
|
||||
onFilter: PropTypes.func
|
||||
onFilter: PropTypes.func,
|
||||
onExternalFilter: PropTypes.func
|
||||
};
|
||||
|
||||
BootstrapTable.defaultProps = {
|
||||
|
||||
@@ -17,13 +17,15 @@ const HeaderCell = (props) => {
|
||||
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 = <filter.Filter { ...filter.props } onFilter={ onFilter } column={ column } />;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -669,4 +669,74 @@ describe('HeaderCell', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when column.filter is defined', () => {
|
||||
const onFilter = jest.fn();
|
||||
const filterProps = { a: 123 };
|
||||
const Filter = () => <div>test</div>;
|
||||
let column;
|
||||
|
||||
beforeEach(() => {
|
||||
onFilter.mockClear();
|
||||
column = {
|
||||
dataField: 'id',
|
||||
text: 'ID',
|
||||
filter: {
|
||||
props: filterProps,
|
||||
Filter
|
||||
}
|
||||
};
|
||||
wrapper = shallow(<HeaderCell column={ column } index={ index } onFilter={ onFilter } />);
|
||||
});
|
||||
|
||||
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 = () => <div>test</div>;
|
||||
const filterRenderer = jest.fn().mockReturnValue(<Filter />);
|
||||
let column;
|
||||
|
||||
beforeEach(() => {
|
||||
onExternalFilter.mockClear();
|
||||
filterRenderer.mockClear();
|
||||
column = {
|
||||
dataField: 'id',
|
||||
text: 'ID',
|
||||
filter: {
|
||||
props: filterProps
|
||||
},
|
||||
filterRenderer
|
||||
};
|
||||
wrapper = shallow(
|
||||
<HeaderCell column={ column } index={ index } onExternalFilter={ onExternalFilter } />);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user