diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js
new file mode 100644
index 0000000..12a5ebc
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js
@@ -0,0 +1,85 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+let priceFilter;
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ getFilter: (filter) => {
+ // pricerFilter was assigned once the component has been mounted.
+ priceFilter = filter;
+ }
+ })
+}];
+
+const handleClick = () => {
+ priceFilter({
+ number: 2103,
+ comparator: Comparator.GT
+ });
+};
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
+
+let priceFilter;
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ getFilter: (filter) => {
+ // pricerFilter was assigned once the component has been mounted.
+ priceFilter = filter;
+ }
+ })
+}];
+
+const handleClick = () => {
+ priceFilter({
+ number: 2103,
+ comparator: Comparator.GT
+ });
+};
+
+export default () => (
+
+
+
+
+
+);
+`;
+
+export default () => (
+
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js
new file mode 100644
index 0000000..d368af5
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js
@@ -0,0 +1,96 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsQualityGenerator } from 'utils/common';
+
+const products = productsQualityGenerator(6);
+
+let qualityFilter;
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quality',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ getFilter: (filter) => {
+ // qualityFilter was assigned once the component has been mounted.
+ qualityFilter = filter;
+ }
+ })
+}];
+
+const handleClick = () => {
+ qualityFilter(0);
+};
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+let qualityFilter;
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quality',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ getFilter: (filter) => {
+ // qualityFilter was assigned once the component has been mounted.
+ qualityFilter = filter;
+ }
+ })
+}];
+
+const handleClick = () => {
+ qualityFilter(0);
+};
+
+export default () => (
+
+
+
+
+
+);
+`;
+
+export default () => (
+
+
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js
new file mode 100644
index 0000000..f1080c0
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js
@@ -0,0 +1,81 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+let nameFilter;
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter({
+ getFilter: (filter) => {
+ // nameFilter was assigned once the component has been mounted.
+ nameFilter = filter;
+ }
+ })
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: textFilter()
+}];
+
+const handleClick = () => {
+ nameFilter(0);
+};
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+
+let nameFilter;
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter({
+ getFilter: (filter) => {
+ // nameFilter was assigned once the component has been mounted.
+ nameFilter = filter;
+ }
+ })
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: textFilter()
+}];
+
+const handleClick = () => {
+ nameFilter(0);
+};
+
+export default () => (
+
+
+
+
+
+);
+`;
+
+export default () => (
+
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 25d8538..7e3ba5e 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -48,6 +48,9 @@ import CustomSelectFilter from 'examples/column-filter/custom-select-filter';
import NumberFilter from 'examples/column-filter/number-filter';
import NumberFilterWithDefaultValue from 'examples/column-filter/number-filter-default-value';
import CustomNumberFilter from 'examples/column-filter/custom-number-filter';
+import ProgrammaticallyTextFilter from 'examples/column-filter/programmatically-text-filter';
+import ProgrammaticallySelectFilter from 'examples/column-filter/programmatically-select-filter';
+import ProgrammaticallyNumberFilter from 'examples/column-filter/programmatically-number-filter';
// work on rows
import RowStyleTable from 'examples/rows/row-style';
@@ -166,7 +169,10 @@ storiesOf('Column Filter', module)
.add('Custom Text Filter', () => )
.add('Custom Select Filter', () => )
.add('Custom Number Filter', () => )
- .add('Custom Filter Value', () => );
+ .add('Custom Filter Value', () => )
+ .add('Programmatically Text Filter ', () => )
+ .add('Programmatically Select Filter ', () => )
+ .add('Programmatically Number Filter ', () => );
storiesOf('Work on Rows', module)
.add('Customize Row Style', () => )
diff --git a/packages/react-bootstrap-table2-filter/src/components/number.js b/packages/react-bootstrap-table2-filter/src/components/number.js
index 3c2b612..ebf55e8 100644
--- a/packages/react-bootstrap-table2-filter/src/components/number.js
+++ b/packages/react-bootstrap-table2-filter/src/components/number.js
@@ -1,3 +1,4 @@
+/* eslint react/require-default-props: 0 */
/* eslint no-return-assign: 0 */
import React, { Component } from 'react';
@@ -30,11 +31,25 @@ class NumberFilter extends Component {
}
componentDidMount() {
- const { column, onFilter } = this.props;
+ const { column, onFilter, getFilter } = this.props;
const comparator = this.numberFilterComparator.value;
const number = this.numberFilter.value;
if (comparator && number) {
- onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number, comparator });
+ }
+
+ // export onFilter function to allow users to access
+ if (getFilter) {
+ getFilter((filterVal) => {
+ this.setState(() => ({ isSelected: (filterVal !== '') }));
+ this.numberFilterComparator.value = filterVal.comparator;
+ this.numberFilter.value = filterVal.number;
+
+ onFilter(column, FILTER_TYPE.NUMBER)({
+ number: filterVal.number,
+ comparator: filterVal.comparator
+ });
+ });
}
}
@@ -53,7 +68,7 @@ class NumberFilter extends Component {
}
const filterValue = e.target.value;
this.timeout = setTimeout(() => {
- onFilter(column, { number: filterValue, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number: filterValue, comparator });
}, delay);
}
@@ -65,7 +80,7 @@ class NumberFilter extends Component {
// if (comparator === '') {
// return;
// }
- onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator });
}
onChangeComparator(e) {
@@ -75,7 +90,7 @@ class NumberFilter extends Component {
// if (value === '') {
// return;
// }
- onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator });
}
getComparatorOptions() {
@@ -116,7 +131,7 @@ class NumberFilter extends Component {
this.setState(() => ({ isSelected: (number !== '') }));
this.numberFilterComparator.value = comparator;
this.numberFilter.value = number;
- onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number, comparator });
}
cleanFiltered() {
@@ -126,7 +141,7 @@ class NumberFilter extends Component {
this.setState(() => ({ isSelected: (value !== '') }));
this.numberFilterComparator.value = comparator;
this.numberFilter.value = value;
- onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator });
}
render() {
@@ -224,7 +239,8 @@ NumberFilter.propTypes = {
comparatorStyle: PropTypes.object,
comparatorClassName: PropTypes.string,
numberStyle: PropTypes.object,
- numberClassName: PropTypes.string
+ numberClassName: PropTypes.string,
+ getFilter: PropTypes.func
};
NumberFilter.defaultProps = {
diff --git a/packages/react-bootstrap-table2-filter/src/components/select.js b/packages/react-bootstrap-table2-filter/src/components/select.js
index 7e17afd..ba2d306 100644
--- a/packages/react-bootstrap-table2-filter/src/components/select.js
+++ b/packages/react-bootstrap-table2-filter/src/components/select.js
@@ -25,9 +25,21 @@ class SelectFilter extends Component {
}
componentDidMount() {
+ const { column, onFilter, getFilter } = this.props;
+
const value = this.selectInput.value;
if (value && value !== '') {
- this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ onFilter(column, FILTER_TYPE.SELECT)(value);
+ }
+
+ // export onFilter function to allow users to access
+ if (getFilter) {
+ getFilter((filterVal) => {
+ this.setState(() => ({ isSelected: filterVal !== '' }));
+ this.selectInput.value = filterVal;
+
+ onFilter(column, FILTER_TYPE.SELECT)(filterVal);
+ });
}
}
@@ -41,7 +53,7 @@ class SelectFilter extends Component {
if (needFilter) {
const value = this.selectInput.value;
if (value) {
- this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value);
}
}
}
@@ -64,19 +76,19 @@ class SelectFilter extends Component {
const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : '';
this.setState(() => ({ isSelected: value !== '' }));
this.selectInput.value = value;
- this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value);
}
applyFilter(value) {
this.selectInput.value = value;
this.setState(() => ({ isSelected: value !== '' }));
- this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value);
}
filter(e) {
const { value } = e.target;
this.setState(() => ({ isSelected: value !== '' }));
- this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value);
}
render() {
@@ -90,6 +102,7 @@ class SelectFilter extends Component {
comparator,
withoutEmptyOption,
caseSensitive,
+ getFilter,
...rest
} = this.props;
@@ -121,7 +134,8 @@ SelectFilter.propTypes = {
className: PropTypes.string,
withoutEmptyOption: PropTypes.bool,
defaultValue: PropTypes.any,
- caseSensitive: PropTypes.bool
+ caseSensitive: PropTypes.bool,
+ getFilter: PropTypes.func
};
SelectFilter.defaultProps = {
diff --git a/packages/react-bootstrap-table2-filter/src/components/text.js b/packages/react-bootstrap-table2-filter/src/components/text.js
index ffbe702..3af8ae2 100644
--- a/packages/react-bootstrap-table2-filter/src/components/text.js
+++ b/packages/react-bootstrap-table2-filter/src/components/text.js
@@ -17,10 +17,21 @@ class TextFilter extends Component {
value: props.defaultValue
};
}
+
componentDidMount() {
+ const { onFilter, getFilter, column } = this.props;
const defaultValue = this.input.value;
+
if (defaultValue) {
- this.props.onFilter(this.props.column, defaultValue, FILTER_TYPE.TEXT);
+ onFilter(this.props.column, FILTER_TYPE.TEXT)(defaultValue);
+ }
+
+ // export onFilter function to allow users to access
+ if (getFilter) {
+ getFilter((filterVal) => {
+ this.setState(() => ({ value: filterVal }));
+ onFilter(column, FILTER_TYPE.TEXT)(filterVal);
+ });
}
}
@@ -40,7 +51,7 @@ class TextFilter extends Component {
const filterValue = e.target.value;
this.setState(() => ({ value: filterValue }));
this.timeout = setTimeout(() => {
- this.props.onFilter(this.props.column, filterValue, FILTER_TYPE.TEXT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(filterValue);
}, this.props.delay);
}
@@ -53,12 +64,12 @@ class TextFilter extends Component {
cleanFiltered() {
const value = this.props.defaultValue;
this.setState(() => ({ value }));
- this.props.onFilter(this.props.column, value, FILTER_TYPE.TEXT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(value);
}
applyFilter(filterText) {
this.setState(() => ({ value: filterText }));
- this.props.onFilter(this.props.column, filterText, FILTER_TYPE.TEXT);
+ this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(filterText);
}
handleClick(e) {
@@ -77,8 +88,10 @@ class TextFilter extends Component {
onFilter,
caseSensitive,
defaultValue,
+ getFilter,
...rest
} = this.props;
+
// stopPropagation for onClick event is try to prevent sort was triggered.
return (
(
data,
dataField,
- { filterVal = '', comparator = LIKE, caseSensitive },
+ { filterVal: userInput = '', comparator = LIKE, caseSensitive },
customFilterValue
-) =>
- data.filter((row) => {
- let cell = _.get(row, dataField);
- if (customFilterValue) {
- cell = customFilterValue(cell, row);
- }
- const cellStr = _.isDefined(cell) ? cell.toString() : '';
- if (comparator === EQ) {
- return cellStr === filterVal;
- }
- if (caseSensitive) {
- return cellStr.includes(filterVal);
- }
- return cellStr.toLocaleUpperCase().indexOf(filterVal.toLocaleUpperCase()) !== -1;
- });
+) => {
+ // make sure filter value to be a string
+ const filterVal = userInput.toString();
+
+ return (
+ data.filter((row) => {
+ let cell = _.get(row, dataField);
+ if (customFilterValue) {
+ cell = customFilterValue(cell, row);
+ }
+ const cellStr = _.isDefined(cell) ? cell.toString() : '';
+ if (comparator === EQ) {
+ return cellStr === filterVal;
+ }
+ if (caseSensitive) {
+ return cellStr.includes(filterVal);
+ }
+
+ return cellStr.toLocaleUpperCase().indexOf(filterVal.toLocaleUpperCase()) !== -1;
+ })
+ );
+};
export const filterByNumber = _ => (
data,
dataField,
{ filterVal: { comparator, number } },
customFilterValue
-) =>
+) => (
data.filter((row) => {
if (number === '' || !comparator) return true;
let valid = true;
@@ -81,7 +88,8 @@ export const filterByNumber = _ => (
}
}
return valid;
- });
+ })
+);
export const filterFactory = _ => (filterType) => {
let filterFn;
diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js
index f48e031..f13e615 100644
--- a/packages/react-bootstrap-table2-filter/src/wrapper.js
+++ b/packages/react-bootstrap-table2-filter/src/wrapper.js
@@ -40,33 +40,43 @@ export default (Base, {
}
}
- onFilter(column, filterVal, filterType) {
- const { store, columns } = this.props;
- const currFilters = Object.assign({}, this.state.currFilters);
- const { dataField, filter } = column;
+ /**
+ * filter the table like below:
+ * onFilter(column, filterType)(filterVal)
+ * @param {Object} column
+ * @param {String} filterType
+ * @param {String} filterVal - user input for filtering.
+ */
+ onFilter(column, filterType) {
+ return (filterVal) => {
+ const { store, columns } = this.props;
+ const currFilters = Object.assign({}, this.state.currFilters);
+ const { dataField, filter } = column;
- if (!_.isDefined(filterVal) || filterVal === '') {
- delete currFilters[dataField];
- } else {
- // select default comparator is EQ, others are LIKE
- const {
- comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE),
- caseSensitive = false
- } = filter.props;
- currFilters[dataField] = { filterVal, filterType, comparator, caseSensitive };
- }
- store.filters = currFilters;
+ if (!_.isDefined(filterVal) || filterVal === '') {
+ delete currFilters[dataField];
+ } else {
+ // select default comparator is EQ, others are LIKE
+ const {
+ comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE),
+ caseSensitive = false
+ } = filter.props;
+ currFilters[dataField] = { filterVal, filterType, comparator, caseSensitive };
+ }
- if (this.isRemoteFiltering() || this.isRemotePagination()) {
- this.handleRemoteFilterChange();
- // when remote filtering is enable, dont set currFilters state
- // in the componentWillReceiveProps,
- // it's the key point that we can know the filter is changed
- return;
- }
+ store.filters = currFilters;
- store.filteredData = filters(store, columns, _)(currFilters);
- this.setState(() => ({ currFilters, isDataChanged: true }));
+ if (this.isRemoteFiltering() || this.isRemotePagination()) {
+ this.handleRemoteFilterChange();
+ // when remote filtering is enable, dont set currFilters state
+ // in the componentWillReceiveProps,
+ // it's the key point that we can know the filter is changed
+ return;
+ }
+
+ store.filteredData = filters(store, columns, _)(currFilters);
+ this.setState(() => ({ currFilters, isDataChanged: true }));
+ };
}
render() {
diff --git a/packages/react-bootstrap-table2-filter/test/components/number.test.js b/packages/react-bootstrap-table2-filter/test/components/number.test.js
index 6ba66f7..3586ec4 100644
--- a/packages/react-bootstrap-table2-filter/test/components/number.test.js
+++ b/packages/react-bootstrap-table2-filter/test/components/number.test.js
@@ -9,7 +9,11 @@ import * as Comparator from '../../src/comparison';
describe('Number Filter', () => {
let wrapper;
+
+ // onFilter(x)(y) = filter result
const onFilter = sinon.stub();
+ const onFilterFirstReturn = sinon.stub();
+
const column = {
dataField: 'price',
text: 'Product Price'
@@ -17,6 +21,9 @@ describe('Number Filter', () => {
afterEach(() => {
onFilter.reset();
+ onFilterFirstReturn.reset();
+
+ onFilter.returns(onFilterFirstReturn);
});
describe('initialization', () => {
@@ -90,6 +97,36 @@ describe('Number Filter', () => {
});
});
+ describe('when props.getFilter is defined', () => {
+ let programmaticallyFilter;
+
+ const comparator = Comparator.EQ;
+ const number = 123;
+
+ const getFilter = (filter) => {
+ programmaticallyFilter = filter;
+ };
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+
+ programmaticallyFilter({ comparator, number });
+ });
+
+ it('should do onFilter correctly when exported function was executed', () => {
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.NUMBER)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith({ comparator, number })).toBeTruthy();
+ });
+
+ it('should setState correctly when exported function was executed', () => {
+ expect(wrapper.state().isSelected).toBeTruthy();
+ });
+ });
+
describe('when defaultValue.number and defaultValue.comparator props is defined', () => {
const number = 203;
const comparator = Comparator.EQ;
@@ -110,8 +147,9 @@ describe('Number Filter', () => {
it('should calling onFilter on componentDidMount', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(
- column, { number: `${number}`, comparator }, FILTER_TYPE.NUMBER)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.NUMBER)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith({ number: `${number}`, comparator })).toBeTruthy();
});
});
diff --git a/packages/react-bootstrap-table2-filter/test/components/select.test.js b/packages/react-bootstrap-table2-filter/test/components/select.test.js
index 2ed39a6..85f9686 100644
--- a/packages/react-bootstrap-table2-filter/test/components/select.test.js
+++ b/packages/react-bootstrap-table2-filter/test/components/select.test.js
@@ -9,19 +9,27 @@ import { FILTER_TYPE } from '../../src/const';
describe('Select Filter', () => {
let wrapper;
let instance;
+
+ // onFilter(x)(y) = filter result
const onFilter = sinon.stub();
+ const onFilterFirstReturn = sinon.stub();
+
const column = {
dataField: 'quality',
text: 'Product Quality'
};
+
const options = {
0: 'Bad',
1: 'Good',
- 2: 'Unknow'
+ 2: 'Unknown'
};
afterEach(() => {
onFilter.reset();
+ onFilterFirstReturn.reset();
+
+ onFilter.returns(onFilterFirstReturn);
});
describe('initialization', () => {
@@ -83,11 +91,48 @@ describe('Select Filter', () => {
it('should calling onFilter on componentDidMount', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy();
});
});
});
+ describe('when props.getFilter is defined', () => {
+ let programmaticallyFilter;
+
+ const filterValue = 'foo';
+
+ const getFilter = (filter) => {
+ programmaticallyFilter = filter;
+ };
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+
+ programmaticallyFilter(filterValue);
+ });
+
+ it('should do onFilter correctly when exported function was executed', () => {
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(filterValue)).toBeTruthy();
+ });
+
+ it('should setState correctly when exported function was executed', () => {
+ expect(instance.state.isSelected).toBeTruthy();
+ });
+ });
+
describe('when placeholder is defined', () => {
const placeholder = 'test';
beforeEach(() => {
@@ -170,8 +215,9 @@ describe('Select Filter', () => {
it('should update', () => {
expect(onFilter.callCount).toBe(2);
- expect(onFilter.calledWith(
- column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.callCount).toBe(2);
+ expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy();
});
});
@@ -198,8 +244,9 @@ describe('Select Filter', () => {
it('should update', () => {
expect(onFilter.callCount).toBe(2);
- expect(onFilter.calledWith(
- column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.callCount).toBe(2);
+ expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy();
});
});
});
@@ -226,7 +273,9 @@ describe('Select Filter', () => {
it('should calling onFilter correctly', () => {
expect(onFilter.callCount).toBe(2);
- expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.callCount).toBe(2);
+ expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy();
});
});
@@ -249,6 +298,7 @@ describe('Select Filter', () => {
it('should calling onFilter correctly', () => {
expect(onFilter.callCount).toBe(1);
+ expect(onFilterFirstReturn.callCount).toBe(1);
});
});
});
@@ -268,8 +318,10 @@ describe('Select Filter', () => {
});
it('should calling onFilter correctly', () => {
- expect(onFilter.callCount).toBe(1);
- expect(onFilter.calledWith(column, value, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(value)).toBeTruthy();
});
});
@@ -289,8 +341,10 @@ describe('Select Filter', () => {
});
it('should calling onFilter correctly', () => {
- expect(onFilter.callCount).toBe(1);
- expect(onFilter.calledWith(column, event.target.value, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(event.target.value)).toBeTruthy();
});
});
});
diff --git a/packages/react-bootstrap-table2-filter/test/components/text.test.js b/packages/react-bootstrap-table2-filter/test/components/text.test.js
index 4a9c282..5a8d297 100644
--- a/packages/react-bootstrap-table2-filter/test/components/text.test.js
+++ b/packages/react-bootstrap-table2-filter/test/components/text.test.js
@@ -9,7 +9,11 @@ jest.useFakeTimers();
describe('Text Filter', () => {
let wrapper;
let instance;
+
+ // onFilter(x)(y) = filter result
const onFilter = sinon.stub();
+ const onFilterFirstReturn = sinon.stub();
+
const column = {
dataField: 'price',
text: 'Price'
@@ -17,6 +21,9 @@ describe('Text Filter', () => {
afterEach(() => {
onFilter.reset();
+ onFilterFirstReturn.reset();
+
+ onFilter.returns(onFilterFirstReturn);
});
describe('initialization', () => {
@@ -58,7 +65,39 @@ describe('Text Filter', () => {
it('should calling onFilter on componentDidMount', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy();
+ });
+ });
+
+ describe('when props.getFilter is defined', () => {
+ let programmaticallyFilter;
+
+ const filterValue = 'foo';
+
+ const getFilter = (filter) => {
+ programmaticallyFilter = filter;
+ };
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+
+ programmaticallyFilter(filterValue);
+ });
+
+ it('should do onFilter correctly when exported function was executed', () => {
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(filterValue)).toBeTruthy();
+ });
+
+ it('should setState correctly when exported function was executed', () => {
+ expect(instance.state.value).toEqual(filterValue);
});
});
@@ -114,7 +153,9 @@ describe('Text Filter', () => {
it('should calling onFilter correctly when props.defaultValue is changed', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(column, nextDefaultValue, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(nextDefaultValue)).toBeTruthy();
});
});
@@ -133,8 +174,9 @@ describe('Text Filter', () => {
it('should calling onFilter correctly', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(
- column, instance.props.defaultValue, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy();
});
});
@@ -154,7 +196,9 @@ describe('Text Filter', () => {
it('should calling onFilter correctly', () => {
expect(onFilter.calledOnce).toBeTruthy();
- expect(onFilter.calledWith(column, filterText, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy();
+ expect(onFilterFirstReturn.calledOnce).toBeTruthy();
+ expect(onFilterFirstReturn.calledWith(filterText)).toBeTruthy();
});
});
diff --git a/packages/react-bootstrap-table2-filter/test/filter.test.js b/packages/react-bootstrap-table2-filter/test/filter.test.js
index ae66a38..2ffd36d 100644
--- a/packages/react-bootstrap-table2-filter/test/filter.test.js
+++ b/packages/react-bootstrap-table2-filter/test/filter.test.js
@@ -42,6 +42,19 @@ describe('filter', () => {
filterFn = filters(store, columns, _);
});
+ describe('when filter value is not a String', () => {
+ it('should transform to string and do the filter', () => {
+ currFilters.name = {
+ filterVal: 3,
+ filterType: FILTER_TYPE.TEXT
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toBeDefined();
+ expect(result).toHaveLength(2);
+ });
+ });
+
describe(`when default comparator is ${LIKE}`, () => {
it('should returning correct result', () => {
currFilters.name = {
diff --git a/packages/react-bootstrap-table2-filter/test/wrapper.test.js b/packages/react-bootstrap-table2-filter/test/wrapper.test.js
index 3d86285..1442658 100644
--- a/packages/react-bootstrap-table2-filter/test/wrapper.test.js
+++ b/packages/react-bootstrap-table2-filter/test/wrapper.test.js
@@ -167,14 +167,14 @@ describe('Wrapper', () => {
it('should setting store object correctly', () => {
filterVals.forEach((filterVal) => {
- instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal);
expect(props.store.filtering).toBeFalsy();
});
});
it('should setting state correctly', () => {
filterVals.forEach((filterVal) => {
- instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(0);
});
@@ -185,12 +185,12 @@ describe('Wrapper', () => {
const filterVal = '3';
it('should setting store object correctly', () => {
- instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal);
expect(props.store.filters).toEqual(instance.state.currFilters);
});
it('should setting state correctly', () => {
- instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(1);
});
@@ -203,7 +203,7 @@ describe('Wrapper', () => {
props = createTableProps();
props.remote = { filter: true };
createFilterWrapper(props);
- instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal);
});
it('should not setting store object correctly', () => {
@@ -222,27 +222,27 @@ describe('Wrapper', () => {
describe('combination', () => {
it('should setting store object correctly', () => {
- instance.onFilter(props.columns[1], '3', FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)('3');
expect(props.store.filters).toEqual(instance.state.currFilters);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(1);
- instance.onFilter(props.columns[1], '2', FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)('2');
expect(props.store.filters).toEqual(instance.state.currFilters);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(1);
- instance.onFilter(props.columns[2], '2', FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[2], FILTER_TYPE.TEXT)('2');
expect(props.store.filters).toEqual(instance.state.currFilters);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(2);
- instance.onFilter(props.columns[2], '', FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[2], FILTER_TYPE.TEXT)('');
expect(props.store.filters).toEqual(instance.state.currFilters);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(1);
- instance.onFilter(props.columns[1], '', FILTER_TYPE.TEXT);
+ instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)('');
expect(props.store.filters).toEqual(instance.state.currFilters);
expect(instance.state.isDataChanged).toBeTruthy();
expect(Object.keys(instance.state.currFilters)).toHaveLength(0);