mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
implement filter
This commit is contained in:
parent
861809d10c
commit
7016e55472
11
packages/react-bootstrap-table2-filter/package.json
Normal file
11
packages/react-bootstrap-table2-filter/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-filter",
|
||||
"version": "0.0.1",
|
||||
"description": "it's the column filter addon for react-bootstrap-table2",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
2
packages/react-bootstrap-table2-filter/src/comparison.js
vendored
Normal file
2
packages/react-bootstrap-table2-filter/src/comparison.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export const LIKE = 'LIKE';
|
||||
export const EQ = '=';
|
||||
93
packages/react-bootstrap-table2-filter/src/components/text.js
vendored
Normal file
93
packages/react-bootstrap-table2-filter/src/components/text.js
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
/* eslint react/require-default-props: 0 */
|
||||
/* eslint react/no-unused-prop-types: 0 */
|
||||
/* eslint no-return-assign: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import { PropTypes } from 'prop-types';
|
||||
|
||||
import { LIKE, EQ } from '../comparison';
|
||||
import { FILTER_TYPE, FILTER_DELAY } from '../const';
|
||||
|
||||
class TextFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.filter = this.filter.bind(this);
|
||||
this.timeout = null;
|
||||
this.state = {
|
||||
value: props.defaultValue
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
const defaultValue = this.input.value;
|
||||
if (defaultValue) {
|
||||
this.props.onFilter(this.props.column, defaultValue, FILTER_TYPE.TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.defaultValue !== this.props.defaultValue) {
|
||||
this.applyFilter(nextProps.defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
filter(e) {
|
||||
e.stopPropagation();
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
const filterValue = e.target.value;
|
||||
this.setState(() => ({ value: filterValue }));
|
||||
this.timeout = setTimeout(() => {
|
||||
this.props.onFilter(this.props.column, filterValue, FILTER_TYPE.TEXT);
|
||||
}, this.props.delay);
|
||||
}
|
||||
|
||||
cleanFiltered() {
|
||||
const value = this.props.defaultValue;
|
||||
this.setState(() => ({ value }));
|
||||
this.props.onFilter(this.props.column, value, FILTER_TYPE.TEXT);
|
||||
}
|
||||
|
||||
applyFilter(filterText) {
|
||||
this.setState(() => ({ value: filterText }));
|
||||
this.props.onFilter(this.props.column, filterText, FILTER_TYPE.TEXT);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { placeholder, column: { text }, style } = this.props;
|
||||
// stopPropagation for onClick event is try to prevent sort was triggered.
|
||||
return (
|
||||
<input
|
||||
ref={ n => this.input = n }
|
||||
type="text"
|
||||
className="filter text-filter form-control"
|
||||
style={ style }
|
||||
onChange={ this.filter }
|
||||
onClick={ e => e.stopPropagation() }
|
||||
placeholder={ placeholder || `Enter ${text}...` }
|
||||
value={ this.state.value }
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TextFilter.propTypes = {
|
||||
onFilter: PropTypes.func.isRequired,
|
||||
comparator: PropTypes.oneOf([LIKE, EQ]),
|
||||
defaultValue: PropTypes.string,
|
||||
delay: PropTypes.number,
|
||||
placeholder: PropTypes.string,
|
||||
column: PropTypes.object,
|
||||
style: PropTypes.object
|
||||
};
|
||||
|
||||
TextFilter.defaultProps = {
|
||||
delay: FILTER_DELAY,
|
||||
defaultValue: ''
|
||||
};
|
||||
|
||||
|
||||
export default TextFilter;
|
||||
5
packages/react-bootstrap-table2-filter/src/const.js
vendored
Normal file
5
packages/react-bootstrap-table2-filter/src/const.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export const FILTER_TYPE = {
|
||||
TEXT: 'TEXT'
|
||||
};
|
||||
|
||||
export const FILTER_DELAY = 500;
|
||||
36
packages/react-bootstrap-table2-filter/src/filter.js
vendored
Normal file
36
packages/react-bootstrap-table2-filter/src/filter.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import { FILTER_TYPE } from './const';
|
||||
import { LIKE, EQ } from './comparison';
|
||||
|
||||
export const filterByText = _ => (data, dataField, { filterVal, comparator = LIKE }) =>
|
||||
data.filter((row) => {
|
||||
const cell = _.get(row, dataField);
|
||||
const cellStr = _.isDefined(cell) ? cell.toString() : '';
|
||||
if (comparator === EQ) {
|
||||
return cellStr === filterVal;
|
||||
}
|
||||
return cellStr.indexOf(filterVal) > -1;
|
||||
});
|
||||
|
||||
export const filterFactory = _ => (filterType) => {
|
||||
let filterFn;
|
||||
switch (filterType) {
|
||||
case FILTER_TYPE.TEXT:
|
||||
filterFn = filterByText(_);
|
||||
break;
|
||||
default:
|
||||
filterFn = filterByText(_);
|
||||
}
|
||||
return filterFn;
|
||||
};
|
||||
|
||||
export const filters = (store, _) => (currFilters) => {
|
||||
const factory = filterFactory(_);
|
||||
let result = store.getAllData();
|
||||
let filterFn;
|
||||
Object.keys(currFilters).forEach((dataField) => {
|
||||
const filterObj = currFilters[dataField];
|
||||
filterFn = factory(filterObj.filterType);
|
||||
result = filterFn(result, dataField, filterObj);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
15
packages/react-bootstrap-table2-filter/src/index.js
vendored
Normal file
15
packages/react-bootstrap-table2-filter/src/index.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import TextFilter from './components/text';
|
||||
import FilterWrapper from './wrapper';
|
||||
import * as Comparison from './comparison';
|
||||
|
||||
export default (options = {}) => ({
|
||||
FilterWrapper,
|
||||
options
|
||||
});
|
||||
|
||||
export const Comparator = Comparison;
|
||||
|
||||
export const textFilter = (props = {}) => ({
|
||||
Filter: TextFilter,
|
||||
props
|
||||
});
|
||||
48
packages/react-bootstrap-table2-filter/src/wrapper.js
vendored
Normal file
48
packages/react-bootstrap-table2-filter/src/wrapper.js
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { filters } from './filter';
|
||||
|
||||
export default class FilterWrapper extends Component {
|
||||
static propTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
baseElement: PropTypes.func.isRequired,
|
||||
_: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { currFilters: {}, isDataChanged: false };
|
||||
this.onFilter = this.onFilter.bind(this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps() {
|
||||
this.setState(() => ({ isDataChanged: false }));
|
||||
}
|
||||
|
||||
onFilter(column, filterVal, filterType) {
|
||||
const { store, _ } = this.props;
|
||||
const { currFilters } = this.state;
|
||||
const { dataField, filter } = column;
|
||||
|
||||
if (!_.isDefined(filterVal) || filterVal === '') {
|
||||
delete currFilters[dataField];
|
||||
} else {
|
||||
const { comparator } = filter.props;
|
||||
currFilters[dataField] = { filterVal, filterType, comparator };
|
||||
}
|
||||
|
||||
store.filteredData = filters(store, _)(currFilters);
|
||||
store.filtering = Object.keys(currFilters).length > 0;
|
||||
|
||||
this.setState(() => ({ currFilters, isDataChanged: true }));
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.baseElement({
|
||||
...this.props,
|
||||
key: 'table',
|
||||
onFilter: this.onFilter,
|
||||
isDataChanged: this.state.isDataChanged
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -6,11 +6,13 @@ import { getRowByRowId } from './rows';
|
||||
export default class Store {
|
||||
constructor(keyField) {
|
||||
this._data = [];
|
||||
this._filteredData = [];
|
||||
this._keyField = keyField;
|
||||
|
||||
this._sortOrder = undefined;
|
||||
this._sortField = undefined;
|
||||
this._selected = [];
|
||||
this._filtering = false;
|
||||
this._isDataChanged = false;
|
||||
}
|
||||
|
||||
edit(rowId, dataField, newValue) {
|
||||
@ -24,12 +26,33 @@ export default class Store {
|
||||
this.data = sort(this)(sortFunc);
|
||||
}
|
||||
|
||||
get data() { return this._data; }
|
||||
set data(data) { this._data = (data ? JSON.parse(JSON.stringify(data)) : []); }
|
||||
getAllData() {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
get data() {
|
||||
if (this._filtering) {
|
||||
return this._filteredData;
|
||||
}
|
||||
return this._data;
|
||||
}
|
||||
set data(data) {
|
||||
if (this._filtering) {
|
||||
this._filteredData = data;
|
||||
} else {
|
||||
this._data = (data ? JSON.parse(JSON.stringify(data)) : []);
|
||||
}
|
||||
}
|
||||
|
||||
get filteredData() { return this._filteredData; }
|
||||
set filteredData(filteredData) { this._filteredData = filteredData; }
|
||||
|
||||
get keyField() { return this._keyField; }
|
||||
set keyField(keyField) { this._keyField = keyField; }
|
||||
|
||||
get isDataChanged() { return this._isDataChanged; }
|
||||
set isDataChanged(isDataChanged) { this._isDataChanged = isDataChanged; }
|
||||
|
||||
get sortOrder() { return this._sortOrder; }
|
||||
set sortOrder(sortOrder) { this._sortOrder = sortOrder; }
|
||||
|
||||
@ -38,4 +61,7 @@ export default class Store {
|
||||
|
||||
get selected() { return this._selected; }
|
||||
set selected(selected) { this._selected = selected; }
|
||||
|
||||
get filtering() { return this._filtering; }
|
||||
set filtering(filtering) { this._filtering = filtering; }
|
||||
}
|
||||
|
||||
@ -22,9 +22,8 @@ export const pureTable = props =>
|
||||
|
||||
export const wrapWithFilter = (props) => {
|
||||
if (props.filter) {
|
||||
const { wrapper } = props.filter;
|
||||
const FilterBase = wrapper(wrapWithSort, _);
|
||||
return React.createElement(FilterBase, { ...props });
|
||||
const { FilterWrapper } = props.filter;
|
||||
return React.createElement(FilterWrapper, { ...props, baseElement: wrapWithSort, _ });
|
||||
}
|
||||
return wrapWithSort(props);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user