From c1aab0008ed855de8ddd346c64166a4d88cb5dd4 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sat, 16 Feb 2019 15:26:53 +0800 Subject: [PATCH] fix #791 --- ...oad-data-on-the-fly-with-default-filter.js | 70 ++++++++++++++++ ...oad-data-on-the-fly-with-default-search.js | 80 +++++++++++++++++++ .../data/load-data-on-the-fly-with-filter.js | 68 ++++++++++++++++ ...a-on-the-fly-with-pagination-and-filter.js | 72 +++++++++++++++++ .../data/load-data-on-the-fly-with-search.js | 80 +++++++++++++++++++ .../stories/index.js | 15 ++++ .../src/context.js | 28 ++++--- .../src/search/context.js | 16 +++- 8 files changed, 416 insertions(+), 13 deletions(-) create mode 100644 packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-filter.js create mode 100644 packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-search.js create mode 100644 packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js create mode 100644 packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-pagination-and-filter.js create mode 100644 packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js diff --git a/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-filter.js b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-filter.js new file mode 100644 index 000000000..60c8a2288 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-filter.js @@ -0,0 +1,70 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; +import { productsGenerator } from 'utils/common'; + +const ProductList = (props) => { + const columns = [ + { + dataField: 'id', + text: 'Product ID' + }, + { + dataField: 'name', + text: 'Product Name', + filter: textFilter({ + defaultValue: '1' + }) + }, + { + dataField: 'price', + text: 'Product Price', + filter: textFilter() + } + ]; + + return ( +
+

Products

+ +
+ ); +}; + +export default class DataContainer extends React.Component { + state = { + products: productsGenerator(3) + }; + + loadData = () => { + this.setState({ + products: productsGenerator(14) + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-search.js b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-search.js new file mode 100644 index 000000000..d9b08c45b --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-default-search.js @@ -0,0 +1,80 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit'; +import { productsGenerator } from 'utils/common'; + +const { SearchBar } = Search; +const ProductList = (props) => { + const columns = [ + { + dataField: 'id', + text: 'Product ID' + }, + { + dataField: 'name', + text: 'Product Name' + }, + { + dataField: 'price', + text: 'Product Price' + } + ]; + + return ( +
+

Products

+ + { + toolkitprops => ( +
+ + +
+ ) + } +
+
+ ); +}; + +export default class DataContainer extends React.Component { + state = { + products: productsGenerator(3) + }; + + loadData = () => { + this.setState({ + products: productsGenerator(14) + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js new file mode 100644 index 000000000..c654034d6 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js @@ -0,0 +1,68 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; +import { productsGenerator } from 'utils/common'; + +const ProductList = (props) => { + const columns = [ + { + dataField: 'id', + text: 'Product ID' + }, + { + dataField: 'name', + text: 'Product Name', + filter: textFilter() + }, + { + dataField: 'price', + text: 'Product Price', + filter: textFilter() + } + ]; + + return ( +
+

Products

+ +
+ ); +}; + +export default class DataContainer extends React.Component { + state = { + products: [] + }; + + loadData = () => { + this.setState({ + products: productsGenerator() + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-pagination-and-filter.js b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-pagination-and-filter.js new file mode 100644 index 000000000..b42a12768 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-pagination-and-filter.js @@ -0,0 +1,72 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; +import paginationFactory from 'react-bootstrap-table2-paginator'; +import { productsGenerator } from 'utils/common'; + +const ProductList = (props) => { + const columns = [ + { + dataField: 'id', + text: 'Product ID' + }, + { + dataField: 'name', + text: 'Product Name', + filter: textFilter({ + defaultValue: '6' + }) + }, + { + dataField: 'price', + text: 'Product Price', + filter: textFilter() + } + ]; + + return ( +
+

Products

+ +
+ ); +}; + +export default class DataContainer extends React.Component { + state = { + products: productsGenerator(60) + }; + + loadData = () => { + this.setState({ + products: productsGenerator(14) + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js new file mode 100644 index 000000000..03540be04 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js @@ -0,0 +1,80 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit'; +import { productsGenerator } from 'utils/common'; + +const { SearchBar } = Search; +const ProductList = (props) => { + const columns = [ + { + dataField: 'id', + text: 'Product ID' + }, + { + dataField: 'name', + text: 'Product Name' + }, + { + dataField: 'price', + text: 'Product Price' + } + ]; + + return ( +
+

Products

+ + { + toolkitprops => ( +
+ + +
+ ) + } +
+
+ ); +}; + +export default class DataContainer extends React.Component { + state = { + products: [] + }; + + loadData = () => { + this.setState({ + products: productsGenerator() + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index a7ed50f7f..788b08324 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -205,6 +205,13 @@ import RemoteSearch from 'examples/remote/remote-search'; import RemoteCellEdit from 'examples/remote/remote-celledit'; import RemoteAll from 'examples/remote/remote-all'; +// data +import LoadDataWithFilter from 'examples/data/load-data-on-the-fly-with-filter'; +import LoadDataWithDefaultFilter from 'examples/data/load-data-on-the-fly-with-default-filter'; +import LoadDataWithSearch from 'examples/data/load-data-on-the-fly-with-search'; +import LoadDataWithDefaultSearch from 'examples/data/load-data-on-the-fly-with-default-search'; +import LoadDataWithPaginationAndFilter from 'examples/data/load-data-on-the-fly-with-pagination-and-filter'; + // css style import 'stories/stylesheet/tomorrow.min.css'; import 'stories/stylesheet/storybook.scss'; @@ -433,3 +440,11 @@ storiesOf('Remote', module) .add('Remote Search', () => ) .add('Remote Cell Editing', () => ) .add('Remote All', () => ); + +storiesOf('Data', module) + .addDecorator(bootstrapStyle()) + .add('Load data with Filter', () => ) + .add('Load data with Default Filter', () => ) + .add('Load data with Search', () => ) + .add('Load data with Default Search', () => ) + .add('Load data with Filter and Pagination', () => ); diff --git a/packages/react-bootstrap-table2-filter/src/context.js b/packages/react-bootstrap-table2-filter/src/context.js index f3edd1fd9..019013faa 100644 --- a/packages/react-bootstrap-table2-filter/src/context.js +++ b/packages/react-bootstrap-table2-filter/src/context.js @@ -25,6 +25,7 @@ export default ( super(props); this.currFilters = {}; this.onFilter = this.onFilter.bind(this); + this.doFilter = this.doFilter.bind(this); this.onExternalFilter = this.onExternalFilter.bind(this); this.state = { data: props.data @@ -38,11 +39,13 @@ export default ( } componentWillReceiveProps(nextProps) { - if (isRemoteFiltering()) { - this.setState({ - data: nextProps.data - }); + let nextData = nextProps.data; + if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.props.data)) { + nextData = this.doFilter(nextProps); } + this.setState({ + data: nextData + }); } onFilter(column, filterType, initialize = false) { @@ -81,11 +84,7 @@ export default ( result = filter.props.onFilter(filterVal); } - const { dataChangeListener, data } = this.props; - result = result || filters(data, this.props.columns, _)(this.currFilters); - if (dataChangeListener) { - dataChangeListener.emit('filterChanged', result.length); - } + result = this.doFilter(this.props, result); this.setState({ data: result }); }; } @@ -96,6 +95,17 @@ export default ( }; } + doFilter(props, customResult) { + let result = customResult; + + const { dataChangeListener, data, columns } = props; + result = result || filters(data, columns, _)(this.currFilters); + if (dataChangeListener) { + dataChangeListener.emit('filterChanged', result.length); + } + return result; + } + render() { return ( { for (let cidx = 0; cidx < columns.length; cidx += 1) { const column = columns[cidx];