refine multiselect

This commit is contained in:
AllenFang 2018-07-31 16:55:17 +08:00
parent 7e29999b40
commit 4e204f1ccd
5 changed files with 75 additions and 23 deletions

View File

@ -1,5 +1,6 @@
/* eslint react/require-default-props: 0 */ /* eslint react/require-default-props: 0 */
/* eslint no-return-assign: 0 */ /* eslint no-return-assign: 0 */
/* eslint no-param-reassign: 0 */
/* eslint react/no-unused-prop-types: 0 */ /* eslint react/no-unused-prop-types: 0 */
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -24,25 +25,24 @@ class MultiSelectFilter extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.filter = this.filter.bind(this); this.filter = this.filter.bind(this);
this.applyFilter = this.applyFilter.bind(this);
const isSelected = props.defaultValue.map(item => props.options[item]).length > 0; const isSelected = props.defaultValue.map(item => props.options[item]).length > 0;
this.state = { isSelected }; this.state = { isSelected };
} }
componentDidMount() { componentDidMount() {
const { column, onFilter, getFilter } = this.props; const { getFilter } = this.props;
const value = getSelections(this.selectInput); const value = getSelections(this.selectInput);
if (value && value.length > 0) { if (value && value.length > 0) {
onFilter(column, FILTER_TYPE.MULTISELECT)(value); this.applyFilter(value);
} }
// export onFilter function to allow users to access // export onFilter function to allow users to access
if (getFilter) { if (getFilter) {
getFilter((filterVal) => { getFilter((filterVal) => {
this.setState(() => ({ isSelected: filterVal.length > 0 }));
this.selectInput.value = filterVal; this.selectInput.value = filterVal;
this.applyFilter(filterVal);
onFilter(column, FILTER_TYPE.MULTISELECT)(filterVal);
}); });
} }
} }
@ -55,10 +55,7 @@ class MultiSelectFilter extends Component {
needFilter = true; needFilter = true;
} }
if (needFilter) { if (needFilter) {
const value = this.selectInput.value; this.applyFilter(this.selectInput.value);
if (value) {
this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value);
}
} }
} }
@ -78,21 +75,21 @@ class MultiSelectFilter extends Component {
cleanFiltered() { cleanFiltered() {
const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : []; const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : [];
this.setState(() => ({ isSelected: value.length > 0 }));
this.selectInput.value = value; this.selectInput.value = value;
this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); this.applyFilter(value);
} }
applyFilter(value) { applyFilter(value) {
this.selectInput.value = value; if (value.length === 1 && value[0] === '') {
value = [];
}
this.setState(() => ({ isSelected: value.length > 0 })); this.setState(() => ({ isSelected: value.length > 0 }));
this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value); this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value);
} }
filter(e) { filter(e) {
const value = getSelections(e.target); const value = getSelections(e.target);
this.setState(() => ({ isSelected: value.length > 0 })); this.applyFilter(value);
this.props.onFilter(this.props.column, FILTER_TYPE.MULTISELECT)(value);
} }
render() { render() {

View File

@ -191,17 +191,21 @@ export const filterByArray = _ => (
data, data,
dataField, dataField,
{ filterVal, comparator } { 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); const cell = _.get(row, dataField);
let cellStr = _.isDefined(cell) ? cell.toString() : ''; let cellStr = _.isDefined(cell) ? cell.toString() : '';
if (comparator === EQ) { if (comparator === EQ) {
return filterVal.indexOf(cellStr) !== -1; return refinedFilterVal.indexOf(cellStr) !== -1;
} }
cellStr = cellStr.toLocaleUpperCase(); 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) => { export const filterFactory = _ => (filterType) => {
let filterFn; let filterFn;

View File

@ -53,8 +53,10 @@ export default (Base, {
const currFilters = Object.assign({}, store.filters); const currFilters = Object.assign({}, store.filters);
const { dataField, filter } = column; const { dataField, filter } = column;
const needClearFilters = !_.isDefined(filterVal) || filterVal === '' || const needClearFilters =
filterVal.length === 0 || (filterVal.length === 1 && filterVal[0] === ''); !_.isDefined(filterVal) ||
filterVal === '' ||
filterVal.length === 0;
if (needClearFilters) { if (needClearFilters) {
delete currFilters[dataField]; delete currFilters[dataField];

View File

@ -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', () => { describe('filterByNumber', () => {
beforeEach(() => { beforeEach(() => {
filterFn = filters(store, columns, _); filterFn = filters(store, columns, _);

View File

@ -163,7 +163,7 @@ describe('Wrapper', () => {
}); });
describe('when filterVal is empty or undefined', () => { describe('when filterVal is empty or undefined', () => {
const filterVals = ['', undefined]; const filterVals = ['', undefined, []];
it('should setting store object correctly', () => { it('should setting store object correctly', () => {
filterVals.forEach((filterVal) => { filterVals.forEach((filterVal) => {