diff --git a/packages/react-bootstrap-table2-filter/src/components/multiselect.js b/packages/react-bootstrap-table2-filter/src/components/multiselect.js index 9630bbd..5f4623b 100644 --- a/packages/react-bootstrap-table2-filter/src/components/multiselect.js +++ b/packages/react-bootstrap-table2-filter/src/components/multiselect.js @@ -1,5 +1,6 @@ /* eslint react/require-default-props: 0 */ /* eslint no-return-assign: 0 */ +/* eslint no-param-reassign: 0 */ /* eslint react/no-unused-prop-types: 0 */ import React, { Component } from 'react'; import PropTypes from 'prop-types'; @@ -24,25 +25,24 @@ class MultiSelectFilter extends Component { constructor(props) { super(props); this.filter = this.filter.bind(this); + this.applyFilter = this.applyFilter.bind(this); const isSelected = props.defaultValue.map(item => props.options[item]).length > 0; this.state = { isSelected }; } componentDidMount() { - const { column, onFilter, getFilter } = this.props; + const { getFilter } = this.props; const value = getSelections(this.selectInput); if (value && value.length > 0) { - onFilter(column, FILTER_TYPE.MULTISELECT)(value); + this.applyFilter(value); } // export onFilter function to allow users to access if (getFilter) { getFilter((filterVal) => { - this.setState(() => ({ isSelected: filterVal.length > 0 })); this.selectInput.value = filterVal; - - onFilter(column, FILTER_TYPE.MULTISELECT)(filterVal); + this.applyFilter(filterVal); }); } } @@ -55,10 +55,7 @@ class MultiSelectFilter extends Component { needFilter = true; } if (needFilter) { - const value = this.selectInput.value; - if (value) { - this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); - } + this.applyFilter(this.selectInput.value); } } @@ -78,21 +75,21 @@ class MultiSelectFilter extends Component { cleanFiltered() { const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : []; - this.setState(() => ({ isSelected: value.length > 0 })); this.selectInput.value = value; - this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); + this.applyFilter(value); } applyFilter(value) { - this.selectInput.value = value; + if (value.length === 1 && value[0] === '') { + value = []; + } this.setState(() => ({ isSelected: value.length > 0 })); this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); } filter(e) { const value = getSelections(e.target); - this.setState(() => ({ isSelected: value.length > 0 })); - this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); + this.applyFilter(value); } render() { diff --git a/packages/react-bootstrap-table2-filter/src/filter.js b/packages/react-bootstrap-table2-filter/src/filter.js index 73d84c4..c1a8666 100644 --- a/packages/react-bootstrap-table2-filter/src/filter.js +++ b/packages/react-bootstrap-table2-filter/src/filter.js @@ -191,17 +191,21 @@ export const filterByArray = _ => ( data, dataField, { filterVal, comparator } -) => ( - data.filter((row) => { +) => { + if (filterVal.length === 0) return data; + const refinedFilterVal = filterVal + .filter(x => _.isDefined(x)) + .map(x => x.toString()); + return data.filter((row) => { const cell = _.get(row, dataField); let cellStr = _.isDefined(cell) ? cell.toString() : ''; if (comparator === EQ) { - return filterVal.indexOf(cellStr) !== -1; + return refinedFilterVal.indexOf(cellStr) !== -1; } cellStr = cellStr.toLocaleUpperCase(); - return filterVal.some(item => cellStr.indexOf(item.toLocaleUpperCase()) !== -1); - }) -); + return refinedFilterVal.some(item => cellStr.indexOf(item.toLocaleUpperCase()) !== -1); + }); +}; 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 0c8fab7..0602ee8 100644 --- a/packages/react-bootstrap-table2-filter/src/wrapper.js +++ b/packages/react-bootstrap-table2-filter/src/wrapper.js @@ -53,8 +53,10 @@ export default (Base, { const currFilters = Object.assign({}, store.filters); const { dataField, filter } = column; - const needClearFilters = !_.isDefined(filterVal) || filterVal === '' || - filterVal.length === 0 || (filterVal.length === 1 && filterVal[0] === ''); + const needClearFilters = + !_.isDefined(filterVal) || + filterVal === '' || + filterVal.length === 0; if (needClearFilters) { delete currFilters[dataField]; diff --git a/packages/react-bootstrap-table2-filter/test/filter.test.js b/packages/react-bootstrap-table2-filter/test/filter.test.js index 25f629d..79d0407 100644 --- a/packages/react-bootstrap-table2-filter/test/filter.test.js +++ b/packages/react-bootstrap-table2-filter/test/filter.test.js @@ -123,6 +123,55 @@ describe('filter', () => { }); }); + describe('filterByArray', () => { + beforeEach(() => { + filterFn = filters(store, columns, _); + }); + + describe('when filter value is empty array', () => { + it('should return original data', () => { + currFilters.name = { + filterVal: [], + filterType: FILTER_TYPE.MULTISELECT + }; + + const result = filterFn(currFilters); + expect(result).toBeDefined(); + expect(result).toHaveLength(store.data.length); + }); + }); + + describe('when filter value is not an empty array', () => { + describe(`and comparator is ${EQ}`, () => { + it('should return data correctly', () => { + currFilters.price = { + filterVal: [201, 203], + filterType: FILTER_TYPE.MULTISELECT, + comparator: EQ + }; + + const result = filterFn(currFilters); + expect(result).toBeDefined(); + expect(result).toHaveLength(2); + }); + }); + + describe(`and comparator is ${LIKE}`, () => { + it('should return data correctly', () => { + currFilters.name = { + filterVal: ['name 3', '5'], + filterType: FILTER_TYPE.MULTISELECT, + comparator: LIKE + }; + + const result = filterFn(currFilters); + expect(result).toBeDefined(); + expect(result).toHaveLength(3); + }); + }); + }); + }); + describe('filterByNumber', () => { beforeEach(() => { filterFn = filters(store, columns, _); diff --git a/packages/react-bootstrap-table2-filter/test/wrapper.test.js b/packages/react-bootstrap-table2-filter/test/wrapper.test.js index 1442658..751fc2e 100644 --- a/packages/react-bootstrap-table2-filter/test/wrapper.test.js +++ b/packages/react-bootstrap-table2-filter/test/wrapper.test.js @@ -163,7 +163,7 @@ describe('Wrapper', () => { }); describe('when filterVal is empty or undefined', () => { - const filterVals = ['', undefined]; + const filterVals = ['', undefined, []]; it('should setting store object correctly', () => { filterVals.forEach((filterVal) => {