From 363a43251ffc99cd54a2c4e89ee271ad8501e407 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sun, 7 Apr 2019 16:49:03 +0800 Subject: [PATCH] fix #891 --- docs/README.md | 17 ++ .../examples/data/data-change-listener.js | 151 ++++++++++++++++++ .../stories/index.js | 2 + .../src/data-context.js | 3 + .../src/bootstrap-table.js | 9 ++ .../src/contexts/index.js | 1 + 6 files changed, 183 insertions(+) create mode 100644 packages/react-bootstrap-table2-example/examples/data/data-change-listener.js diff --git a/docs/README.md b/docs/README.md index 3fc1c58..dc12d3a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,6 +33,7 @@ * [pagination](#pagination) * [filter](#filter) * [onTableChange](#onTableChange) +* [onDataSizeChange](#onDataSizeChange) ### keyField(**required**) - [String] Tells `react-bootstrap-table2` which column is unique. @@ -317,4 +318,20 @@ Following is a shape of `newState` newValue } } +``` + +### onDataSizeChange - [Function] +This callback function will be called only when data size change by search/filter etc. This function have one argument which is an object contains below props: + +* `dataSize`: The new data size + +```js +handleDataChange = ({ dataSize }) => { + this.setState({ rowCount: dataSize }); +} + + ``` \ No newline at end of file diff --git a/packages/react-bootstrap-table2-example/examples/data/data-change-listener.js b/packages/react-bootstrap-table2-example/examples/data/data-change-listener.js new file mode 100644 index 0000000..3b9f737 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/data/data-change-listener.js @@ -0,0 +1,151 @@ +/* eslint react/no-multi-comp: 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 Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name', + filter: textFilter() +}, { + dataField: 'price', + text: 'Product Price', + filter: textFilter() +}]; + +const sourceCode1 = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; + +class Case1 extends React.Component { + constructor(props) { + super(props); + this.state = { rowCount: products.length }; + } + + handleDataChange = ({ dataSize }) => { + this.setState({ rowCount: dataSize }); + } + + render() { + return ( +
+
Row Count:{ this.state.rowCount }
+ + { sourceCode } +
+ ); + } +`; + +const sourceCode2 = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; +import paginationFactory from 'react-bootstrap-table2-paginator'; + +class Case2 extends React.Component { + constructor(props) { + super(props); + this.state = { rowCount: products.length }; + } + + handleDataChange = ({ dataSize }) => { + this.setState({ rowCount: dataSize }); + } + + render() { + return ( +
+
Row Count:{ this.state.rowCount }
+ + { sourceCode } +
+ ); + } +`; + +const products1 = productsGenerator(8); +class WithoutPaginationCase extends React.Component { + constructor(props) { + super(props); + this.state = { rowCount: products1.length }; + } + + handleDataChange = ({ dataSize }) => { + this.setState({ rowCount: dataSize }); + } + + render() { + return ( +
+

Without Pagination Case

+
Row Count:{ this.state.rowCount }
+ + { sourceCode2 } +
+ ); + } +} + +const products2 = productsGenerator(88); +class WithPaginationCase extends React.Component { + constructor(props) { + super(props); + this.state = { rowCount: products2.length }; + } + + handleDataChange = ({ dataSize }) => { + this.setState({ rowCount: dataSize }); + } + + render() { + return ( +
+

Without Pagination Case

+
Row Count:{ this.state.rowCount }
+ + { sourceCode1 } +
+ ); + } +} + +export default () => ( +
+ + +
+); + diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index d35cbcb..9bd79b8 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -217,6 +217,7 @@ import RemoteCellEdit from 'examples/remote/remote-celledit'; import RemoteAll from 'examples/remote/remote-all'; // data +import DataChangeListener from 'examples/data/data-change-listener'; 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'; @@ -467,6 +468,7 @@ storiesOf('Remote', module) storiesOf('Data', module) .addDecorator(bootstrapStyle()) + .add('Data Change Listener', () => ) .add('Load data with Filter', () => ) .add('Load data with Default Filter', () => ) .add('Load data with Search', () => ) diff --git a/packages/react-bootstrap-table2-paginator/src/data-context.js b/packages/react-bootstrap-table2-paginator/src/data-context.js index e33f45f..654e9f8 100644 --- a/packages/react-bootstrap-table2-paginator/src/data-context.js +++ b/packages/react-bootstrap-table2-paginator/src/data-context.js @@ -46,6 +46,9 @@ class PaginationDataProvider extends Provider { this.currPage = newPage; } } + if (nextProps.onDataSizeChange && nextProps.data.length !== this.props.data.length) { + nextProps.onDataSizeChange({ dataSize: nextProps.data.length }); + } } isRemotePagination = () => this.props.isRemotePagination(); diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index 0df430c..bc0bc79 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -18,6 +18,14 @@ class BootstrapTable extends PropsBaseResolver(Component) { this.validateProps(); } + componentWillReceiveProps(nextProps) { + if (nextProps.onDataSizeChange && !nextProps.pagination) { + if (nextProps.data.length !== this.props.data.length) { + nextProps.onDataSizeChange({ dataSize: nextProps.data.length }); + } + } + } + // Exposed APIs getData = () => { return this.visibleRows(); @@ -192,6 +200,7 @@ BootstrapTable.propTypes = { onSort: PropTypes.func, onFilter: PropTypes.func, onExternalFilter: PropTypes.func, + onDataSizeChange: PropTypes.func, // Inject from toolkit search: PropTypes.shape({ searchText: PropTypes.string, diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index 148e805..1df8d6c 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -211,6 +211,7 @@ const withContext = Base => bootstrap4={ this.props.bootstrap4 } isRemotePagination={ this.isRemotePagination } remoteEmitter={ this.remoteEmitter } + onDataSizeChange={ this.props.onDataSizeChange } > {