diff --git a/packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js b/packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
new file mode 100644
index 0000000..cdd6f3d
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
@@ -0,0 +1,150 @@
+import React from 'react';
+
+import BootstrapTable from 'react-bootstrap-table-next';
+import paginationFactory from 'react-bootstrap-table2-paginator';
+import Code from 'components/common/code-block';
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import paginationFactory from 'react-bootstrap-table2-paginator';
+
+class BookList extends React.Component {
+ state = {
+ books: [
+ { id: '1', name: 'Book 1' },
+ { id: '2', name: 'Book 2' },
+ { id: '3', name: 'Book 3' },
+ { id: '4', name: 'Book 4' },
+ { id: '5', name: 'Book 5' },
+ { id: '6', name: 'Book 6' }
+ ]
+ };
+
+ deleteBookWithId = () => {
+ const lastOneId = this.state.books.length;
+ const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
+ this.setState({ books: updatedBooks });
+ };
+
+ addBook = () => {
+ const lastOneId = this.state.books.length + 1;
+ this.setState({ books: [...this.state.books, {
+ id: \`$\{lastOneId}\`, name: \`Book $\{lastOneId}\`
+ }] });
+ }
+
+ render() {
+ const options = {
+ // pageStartIndex: 0,
+ sizePerPage: 5,
+ hideSizePerPage: true,
+ hidePageListOnlyOnePage: true
+ };
+ const columns = [
+ {
+ dataField: 'id',
+ text: 'Product ID',
+ Cell: row => (
+
+ { row.value }
+
+ )
+ },
+ {
+ dataField: 'name',
+ text: 'Product Name'
+ }
+ ];
+
+ return (
+
+
+
+
+ { sourceCode }
+
+ );
+ }
+`;
+
+export default class BookList extends React.Component {
+ state = {
+ books: [
+ { id: '1', name: 'Book 1' },
+ { id: '2', name: 'Book 2' },
+ { id: '3', name: 'Book 3' },
+ { id: '4', name: 'Book 4' },
+ { id: '5', name: 'Book 5' },
+ { id: '6', name: 'Book 6' },
+ { id: '7', name: 'Book 6' },
+ { id: '8', name: 'Book 6' },
+ { id: '9', name: 'Book 6' },
+ { id: '10', name: 'Book 6' },
+ { id: '11', name: 'Book 6' }
+ ]
+ };
+
+ deleteBookWithId = () => {
+ const lastOneId = this.state.books.length;
+ const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
+ this.setState({ books: updatedBooks });
+ };
+
+ addBook = () => {
+ const lastOneId = this.state.books.length + 1;
+ this.setState({ books: [...this.state.books, {
+ id: `${lastOneId}`, name: `Book ${lastOneId}`
+ }] });
+ }
+
+ render() {
+ const options = {
+ // pageStartIndex: 0,
+ sizePerPage: 5,
+ hideSizePerPage: true,
+ hidePageListOnlyOnePage: true
+ };
+ const columns = [
+ {
+ dataField: 'id',
+ text: 'Product ID',
+ Cell: row => (
+
+ { row.value }
+
+ )
+ },
+ {
+ dataField: 'name',
+ text: 'Product Name'
+ }
+ ];
+
+ return (
+
+
+
+
+ { sourceCode }
+
+ );
+ }
+}
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 39be4b7..cc97704 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -163,6 +163,7 @@ import ExpandHooks from 'examples/row-expand/expand-hooks';
// pagination
import PaginationTable from 'examples/pagination';
import PaginationHooksTable from 'examples/pagination/pagination-hooks';
+import PaginationWithDynamicData from 'examples/pagination/pagination-with-dynamic-data';
import CustomPaginationTable from 'examples/pagination/custom-pagination';
import CustomPageButtonTable from 'examples/pagination/custom-page-button';
import CustomSizePerPageOptionTable from 'examples/pagination/custom-size-per-page-option';
@@ -404,6 +405,7 @@ storiesOf('Pagination', module)
.addDecorator(bootstrapStyle())
.add('Basic Pagination Table', () => )
.add('Pagination Hooks', () => )
+ .add('Pagination with Dynamic Data', () => )
.add('Custom Pagination', () => )
.add('Custom Page Button', () => )
.add('Custom Page List', () => )
diff --git a/packages/react-bootstrap-table2-paginator/src/data-context.js b/packages/react-bootstrap-table2-paginator/src/data-context.js
index d9e9e01..e33f45f 100644
--- a/packages/react-bootstrap-table2-paginator/src/data-context.js
+++ b/packages/react-bootstrap-table2-paginator/src/data-context.js
@@ -32,7 +32,12 @@ class PaginationDataProvider extends Provider {
// user should align the page when the page is not fit to the data size when remote enable
if (!this.isRemotePagination() && !custom) {
const newPage = alignPage(
- nextProps.data.length, this.currPage, currSizePerPage, pageStartIndex);
+ nextProps.data.length,
+ this.props.data.length,
+ this.currPage,
+ currSizePerPage,
+ pageStartIndex
+ );
if (this.currPage !== newPage) {
if (onPageChange) {
diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js
index 1e3e82b..5b63463 100644
--- a/packages/react-bootstrap-table2-paginator/src/page.js
+++ b/packages/react-bootstrap-table2-paginator/src/page.js
@@ -1,3 +1,5 @@
+import Const from './const';
+
const getNormalizedPage = (
page,
pageStartIndex
@@ -19,12 +21,20 @@ const startIndex = (
export const alignPage = (
dataSize,
+ prevDataSize,
page,
sizePerPage,
pageStartIndex
) => {
- if (page < pageStartIndex || page > (Math.floor(dataSize / sizePerPage) + pageStartIndex)) {
- return pageStartIndex;
+ if (prevDataSize < dataSize) return page;
+ if (page < pageStartIndex) return pageStartIndex;
+ if (dataSize <= 0) return pageStartIndex;
+ if ((page >= (Math.floor(dataSize / sizePerPage) + pageStartIndex)) && pageStartIndex === 1) {
+ return Math.ceil(dataSize / sizePerPage);
+ }
+ if (page >= Math.floor(dataSize / sizePerPage) && pageStartIndex === 0) {
+ const newPage = Math.ceil(dataSize / sizePerPage);
+ return newPage - Math.abs((Const.PAGE_START_INDEX - pageStartIndex));
}
return page;
};
diff --git a/packages/react-bootstrap-table2-paginator/src/state-context.js b/packages/react-bootstrap-table2-paginator/src/state-context.js
index 91159f6..83fb4da 100644
--- a/packages/react-bootstrap-table2-paginator/src/state-context.js
+++ b/packages/react-bootstrap-table2-paginator/src/state-context.js
@@ -117,13 +117,14 @@ class StateProvider extends React.Component {
const { pagination: { options } } = this.props;
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
Const.PAGE_START_INDEX : options.pageStartIndex;
- this.dataSize = newDataSize;
this.currPage = alignPage(
newDataSize,
+ this.dataSize,
this.currPage,
this.currSizePerPage,
pageStartIndex
);
+ this.dataSize = newDataSize;
this.forceUpdate();
}
diff --git a/packages/react-bootstrap-table2-paginator/test/page.test.js b/packages/react-bootstrap-table2-paginator/test/page.test.js
index aa20c33..e12ae28 100644
--- a/packages/react-bootstrap-table2-paginator/test/page.test.js
+++ b/packages/react-bootstrap-table2-paginator/test/page.test.js
@@ -43,18 +43,132 @@ describe('Page Functions', () => {
});
describe('alignPage', () => {
- const pageStartIndex = 1;
- const sizePerPage = 10;
- const page = 3;
- describe('if the page does not fit the pages which calculated from the length of data', () => {
- it('should return pageStartIndex argument', () => {
- expect(alignPage(15, page, sizePerPage, pageStartIndex)).toEqual(pageStartIndex);
+ let newDataSize;
+ let prevDataSize;
+ let currPage;
+ let pageStartIndex;
+ let sizePerPage;
+
+ describe('if prevDataSize < newDataSize', () => {
+ beforeEach(() => {
+ newDataSize = 10;
+ prevDataSize = 6;
+ currPage = 2;
+ pageStartIndex = 1;
+ sizePerPage = 5;
+ });
+ it('should return same page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(currPage);
});
});
- describe('if the length of store.data is large than the end page index', () => {
- it('should return current page', () => {
- expect(alignPage(30, page, sizePerPage, pageStartIndex)).toEqual(page);
+ describe('if currPage < newDataSize', () => {
+ beforeEach(() => {
+ newDataSize = 10;
+ prevDataSize = 12;
+ currPage = 0;
+ pageStartIndex = 1;
+ sizePerPage = 5;
+ });
+
+ it('should return correct page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(pageStartIndex);
+ });
+ });
+
+ describe('if partStartIndex is default 1', () => {
+ describe('and currPage is bigger than newest last page', () => {
+ beforeEach(() => {
+ newDataSize = 9;
+ prevDataSize = 12;
+ currPage = 3;
+ pageStartIndex = 1;
+ sizePerPage = 5;
+ });
+
+ it('should return correct page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(2);
+ });
+ });
+
+ describe('and currPage is short than newest last page', () => {
+ beforeEach(() => {
+ newDataSize = 11;
+ prevDataSize = 12;
+ currPage = 3;
+ pageStartIndex = 1;
+ sizePerPage = 5;
+ });
+
+ it('should return correct page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(currPage);
+ });
+ });
+ });
+
+ describe('if partStartIndex is default 0', () => {
+ describe('and currPage is bigger than newest last page', () => {
+ beforeEach(() => {
+ newDataSize = 8;
+ prevDataSize = 11;
+ currPage = 2;
+ pageStartIndex = 0;
+ sizePerPage = 5;
+ });
+
+ it('should return correct page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(1);
+ });
+ });
+
+ describe('and currPage is short than newest last page', () => {
+ beforeEach(() => {
+ newDataSize = 11;
+ prevDataSize = 12;
+ currPage = 2;
+ pageStartIndex = 0;
+ sizePerPage = 5;
+ });
+
+ it('should return correct page', () => {
+ expect(alignPage(
+ newDataSize,
+ prevDataSize,
+ currPage,
+ sizePerPage,
+ pageStartIndex
+ )).toEqual(currPage);
+ });
});
});
});