diff --git a/packages/react-bootstrap-table2-paginator/index.js b/packages/react-bootstrap-table2-paginator/index.js
index 8750183..8b20636 100644
--- a/packages/react-bootstrap-table2-paginator/index.js
+++ b/packages/react-bootstrap-table2-paginator/index.js
@@ -1,6 +1,23 @@
-import createContext from './src/context';
+import React from 'react';
+import PropTypes from 'prop-types';
+import createBaseContext from './src/state-context';
+import createDataContext from './src/data-context';
export default (options = {}) => ({
- createContext,
+ createContext: createDataContext,
options
});
+
+const { Provider, Consumer } = createBaseContext();
+
+const CustomizableProvider = props => (
+
+ { paginationProps => props.children(paginationProps) }
+
+);
+
+CustomizableProvider.propTypes = {
+ children: PropTypes.func.isRequired
+};
+
+export const PaginationProvider = CustomizableProvider;
diff --git a/packages/react-bootstrap-table2-paginator/src/context.js b/packages/react-bootstrap-table2-paginator/src/context.js
deleted file mode 100644
index d5ffb96..0000000
--- a/packages/react-bootstrap-table2-paginator/src/context.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* eslint react/prop-types: 0 */
-/* eslint react/require-default-props: 0 */
-/* eslint no-lonely-if: 0 */
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import Const from './const';
-import { BootstrapContext } from './bootstrap';
-import Pagination from './pagination';
-import { getByCurrPage, alignPage } from './page';
-
-export default (
- isRemotePagination,
- handleRemotePageChange
-) => {
- const PaginationContext = React.createContext();
-
- class PaginationProvider extends React.Component {
- static propTypes = {
- data: PropTypes.array.isRequired
- }
-
- constructor(props) {
- super(props);
- this.handleChangePage = this.handleChangePage.bind(this);
- this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
-
- let currPage;
- let currSizePerPage;
- const { options } = props.pagination;
- const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
-
- // initialize current page
- if (typeof options.page !== 'undefined') {
- currPage = options.page;
- } else if (typeof options.pageStartIndex !== 'undefined') {
- currPage = options.pageStartIndex;
- } else {
- currPage = Const.PAGE_START_INDEX;
- }
-
- // initialize current sizePerPage
- if (typeof options.sizePerPage !== 'undefined') {
- currSizePerPage = options.sizePerPage;
- } else if (typeof sizePerPageList[0] === 'object') {
- currSizePerPage = sizePerPageList[0].value;
- } else {
- currSizePerPage = sizePerPageList[0];
- }
-
- this.currPage = currPage;
- this.currSizePerPage = currSizePerPage;
- }
-
- componentWillReceiveProps(nextProps) {
- let needNewState = false;
- let { currPage } = this;
- const { currSizePerPage } = this;
- const { onPageChange } = nextProps.pagination.options;
-
- const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
- nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
-
- // user should align the page when the page is not fit to the data size when remote enable
- if (!isRemotePagination()) {
- const newPage = alignPage(nextProps.data, currPage, currSizePerPage, pageStartIndex);
- if (currPage !== newPage) {
- currPage = newPage;
- needNewState = true;
- }
- } else {
- this.currPage = nextProps.pagination.options.page;
- this.currSizePerPage = nextProps.pagination.options.sizePerPage;
- }
-
- if (needNewState) {
- if (onPageChange) {
- onPageChange(currPage, currSizePerPage);
- }
- this.currPage = currPage;
- this.currSizePerPage = currSizePerPage;
- }
- }
-
- handleChangePage(currPage) {
- const { currSizePerPage } = this;
- const { pagination: { options } } = this.props;
-
- if (options.onPageChange) {
- options.onPageChange(currPage, currSizePerPage);
- }
-
- this.currPage = currPage;
-
- if (isRemotePagination()) {
- handleRemotePageChange(currPage, currSizePerPage);
- return;
- }
- this.forceUpdate();
- }
-
- handleChangeSizePerPage(currSizePerPage, currPage) {
- const { pagination: { options } } = this.props;
-
- if (options.onSizePerPageChange) {
- options.onSizePerPageChange(currSizePerPage, currPage);
- }
-
- this.currPage = currPage;
- this.currSizePerPage = currSizePerPage;
-
- if (isRemotePagination()) {
- handleRemotePageChange(currPage, currSizePerPage);
- return;
- }
- this.forceUpdate();
- }
-
- render() {
- let { data } = this.props;
- const { pagination: { options }, bootstrap4 } = this.props;
- const { currPage, currSizePerPage } = this;
- const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
- Const.With_FIRST_AND_LAST : options.withFirstAndLast;
- const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
- Const.SHOW_ALL_PAGE_BTNS : options.alwaysShowAllBtns;
- const hideSizePerPage = typeof options.hideSizePerPage === 'undefined' ?
- Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
- const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
- Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
- const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
- Const.PAGE_START_INDEX : options.pageStartIndex;
-
- data = isRemotePagination() ?
- data :
- getByCurrPage(
- data,
- currPage,
- currSizePerPage,
- pageStartIndex
- );
-
- return (
-
- { this.props.children }
-
-
-
-
- );
- }
- }
-
- return {
- Provider: PaginationProvider,
- Consumer: PaginationContext.Consumer
- };
-};
diff --git a/packages/react-bootstrap-table2-paginator/src/data-context.js b/packages/react-bootstrap-table2-paginator/src/data-context.js
new file mode 100644
index 0000000..d9e9e01
--- /dev/null
+++ b/packages/react-bootstrap-table2-paginator/src/data-context.js
@@ -0,0 +1,100 @@
+/* eslint react/prop-types: 0 */
+/* eslint react/require-default-props: 0 */
+/* eslint no-lonely-if: 0 */
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Const from './const';
+import { BootstrapContext } from './bootstrap';
+import Pagination from './pagination';
+import { getByCurrPage, alignPage } from './page';
+import createBaseContext from './state-context';
+
+const { Provider } = createBaseContext();
+
+const PaginationDataContext = React.createContext();
+
+class PaginationDataProvider extends Provider {
+ static propTypes = {
+ data: PropTypes.array.isRequired,
+ remoteEmitter: PropTypes.object.isRequired,
+ isRemotePagination: PropTypes.func.isRequired
+ }
+
+ componentWillReceiveProps(nextProps) {
+ super.componentWillReceiveProps(nextProps);
+ const { currSizePerPage } = this;
+ const { custom, onPageChange } = nextProps.pagination.options;
+
+ const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
+ nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
+
+ // 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);
+
+ if (this.currPage !== newPage) {
+ if (onPageChange) {
+ onPageChange(newPage, currSizePerPage);
+ }
+ this.currPage = newPage;
+ }
+ }
+ }
+
+ isRemotePagination = () => this.props.isRemotePagination();
+
+ renderDefaultPagination = () => {
+ if (!this.props.pagination.options.custom) {
+ const {
+ bootstrap4,
+ page: currPage,
+ sizePerPage: currSizePerPage,
+ dataSize,
+ ...rest
+ } = this.getPaginationProps();
+ return (
+
+
+
+ );
+ }
+ return null;
+ }
+
+ render() {
+ let { data } = this.props;
+ const { pagination: { options } } = this.props;
+ const { currPage, currSizePerPage } = this;
+ const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
+ Const.PAGE_START_INDEX : options.pageStartIndex;
+
+ data = this.isRemotePagination() ?
+ data :
+ getByCurrPage(
+ data,
+ currPage,
+ currSizePerPage,
+ pageStartIndex
+ );
+
+ return (
+
+ { this.props.children }
+ { this.renderDefaultPagination() }
+
+ );
+ }
+}
+
+export default () => ({
+ Provider: PaginationDataProvider,
+ Consumer: PaginationDataContext.Consumer
+});
diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js
index feb1f0a..1e3e82b 100644
--- a/packages/react-bootstrap-table2-paginator/src/page.js
+++ b/packages/react-bootstrap-table2-paginator/src/page.js
@@ -18,13 +18,11 @@ const startIndex = (
) => end - (sizePerPage - 1);
export const alignPage = (
- data,
+ dataSize,
page,
sizePerPage,
pageStartIndex
) => {
- const dataSize = data.length;
-
if (page < pageStartIndex || page > (Math.floor(dataSize / sizePerPage) + pageStartIndex)) {
return pageStartIndex;
}
diff --git a/packages/react-bootstrap-table2-paginator/src/state-context.js b/packages/react-bootstrap-table2-paginator/src/state-context.js
new file mode 100644
index 0000000..122b62b
--- /dev/null
+++ b/packages/react-bootstrap-table2-paginator/src/state-context.js
@@ -0,0 +1,163 @@
+/* eslint react/prop-types: 0 */
+/* eslint react/require-default-props: 0 */
+/* eslint no-lonely-if: 0 */
+import React from 'react';
+import Const from './const';
+
+const StateContext = React.createContext();
+
+class StateProvider extends React.Component {
+ constructor(props) {
+ super(props);
+ this.handleChangePage = this.handleChangePage.bind(this);
+ this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
+
+ let currPage;
+ let currSizePerPage;
+ const { options } = props.pagination;
+ const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
+
+ // initialize current page
+ if (typeof options.page !== 'undefined') {
+ currPage = options.page;
+ } else if (typeof options.pageStartIndex !== 'undefined') {
+ currPage = options.pageStartIndex;
+ } else {
+ currPage = Const.PAGE_START_INDEX;
+ }
+
+ // initialize current sizePerPage
+ if (typeof options.sizePerPage !== 'undefined') {
+ currSizePerPage = options.sizePerPage;
+ } else if (typeof sizePerPageList[0] === 'object') {
+ currSizePerPage = sizePerPageList[0].value;
+ } else {
+ currSizePerPage = sizePerPageList[0];
+ }
+
+ this.currPage = currPage;
+ this.currSizePerPage = currSizePerPage;
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const { custom } = nextProps.pagination.options;
+
+ // user should align the page when the page is not fit to the data size when remote enable
+ if (this.isRemotePagination() || custom) {
+ this.currPage = nextProps.pagination.options.page;
+ this.currSizePerPage = nextProps.pagination.options.sizePerPage;
+ }
+ }
+
+ getPaginationProps = () => {
+ const { pagination: { options }, bootstrap4 } = this.props;
+ const { currPage, currSizePerPage } = this;
+ const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
+ Const.With_FIRST_AND_LAST : options.withFirstAndLast;
+ const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
+ Const.SHOW_ALL_PAGE_BTNS : options.alwaysShowAllBtns;
+ const hideSizePerPage = typeof options.hideSizePerPage === 'undefined' ?
+ Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
+ const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
+ Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
+ const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
+ Const.PAGE_START_INDEX : options.pageStartIndex;
+ return {
+ ...options,
+ bootstrap4,
+ page: currPage,
+ sizePerPage: currSizePerPage,
+ pageStartIndex,
+ hidePageListOnlyOnePage,
+ hideSizePerPage,
+ alwaysShowAllBtns,
+ withFirstAndLast,
+ dataSize: options.totalSize,
+ sizePerPageList: options.sizePerPageList || Const.SIZE_PER_PAGE_LIST,
+ paginationSize: options.paginationSize || Const.PAGINATION_SIZE,
+ showTotal: options.showTotal,
+ paginationTotalRenderer: options.paginationTotalRenderer,
+ firstPageText: options.firstPageText || Const.FIRST_PAGE_TEXT,
+ prePageText: options.prePageText || Const.PRE_PAGE_TEXT,
+ nextPageText: options.nextPageText || Const.NEXT_PAGE_TEXT,
+ lastPageText: options.lastPageText || Const.LAST_PAGE_TEXT,
+ prePageTitle: options.prePageTitle || Const.PRE_PAGE_TITLE,
+ nextPageTitle: options.nextPageTitle || Const.NEXT_PAGE_TITLE,
+ firstPageTitle: options.firstPageTitle || Const.FIRST_PAGE_TITLE,
+ lastPageTitle: options.lastPageTitle || Const.LAST_PAGE_TITLE,
+ onPageChange: this.handleChangePage,
+ onSizePerPageChange: this.handleChangeSizePerPage
+ };
+ }
+
+ setPaginationRemoteEmitter = (remoteEmitter) => {
+ this.remoteEmitter = remoteEmitter;
+ }
+
+ isRemotePagination = () => {
+ const e = {};
+ this.remoteEmitter.emit('isRemotePagination', e);
+ return e.result;
+ };
+
+ handleChangePage(currPage) {
+ const { currSizePerPage } = this;
+ const { pagination: { options } } = this.props;
+
+ if (options.onPageChange) {
+ options.onPageChange(currPage, currSizePerPage);
+ }
+
+ this.currPage = currPage;
+
+ if (this.isRemotePagination()) {
+ this.remoteEmitter.emit('paginationChange', currPage, currSizePerPage);
+ return;
+ }
+ this.forceUpdate();
+ }
+
+ handleChangeSizePerPage(currSizePerPage, currPage) {
+ const { pagination: { options } } = this.props;
+
+ if (options.onSizePerPageChange) {
+ options.onSizePerPageChange(currSizePerPage, currPage);
+ }
+
+ this.currPage = currPage;
+ this.currSizePerPage = currSizePerPage;
+
+ if (this.isRemotePagination()) {
+ this.remoteEmitter.emit('paginationChange', currPage, currSizePerPage);
+ return;
+ }
+ this.forceUpdate();
+ }
+
+ render() {
+ const paginationProps = this.getPaginationProps();
+ const pagination = {
+ ...this.props.pagination,
+ options: paginationProps
+ };
+
+ return (
+
+ { this.props.children }
+
+ );
+ }
+}
+
+export default () => ({
+ Provider: StateProvider,
+ Consumer: StateContext.Consumer
+});
diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js
index dc2f6a7..12bfb9a 100644
--- a/packages/react-bootstrap-table2/src/contexts/index.js
+++ b/packages/react-bootstrap-table2/src/contexts/index.js
@@ -40,8 +40,7 @@ const withContext = Base =>
}
if (props.pagination) {
- this.PaginationContext = props.pagination.createContext(
- this.isRemotePagination, this.handleRemotePageChange);
+ this.PaginationContext = props.pagination.createContext();
}
if (props.search && props.search.searchContext) {
@@ -52,6 +51,10 @@ const withContext = Base =>
if (props.setDependencyModules) {
props.setDependencyModules(_);
}
+
+ if (props.setPaginationRemoteEmitter) {
+ props.setPaginationRemoteEmitter(this.remoteEmitter);
+ }
}
componentWillReceiveProps(nextProps) {
@@ -150,6 +153,8 @@ const withContext = Base =>
pagination={ this.props.pagination }
data={ rootProps.getData(filterProps, searchProps, sortProps) }
bootstrap4={ this.props.bootstrap4 }
+ isRemotePagination={ this.isRemotePagination }
+ remoteEmitter={ this.remoteEmitter }
>
{
diff --git a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js
index 89af4c6..b8f4935 100644
--- a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js
+++ b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js
@@ -1,7 +1,15 @@
+import EventEmitter from 'events';
import _ from '../utils';
export default ExtendBase =>
class RemoteResolver extends ExtendBase {
+ constructor(props) {
+ super(props);
+ this.remoteEmitter = new EventEmitter();
+ this.remoteEmitter.on('paginationChange', this.handleRemotePageChange);
+ this.remoteEmitter.on('isRemotePagination', this.isRemotePagination);
+ }
+
getNewestState = (state = {}) => {
let sortOrder;
let sortField;
@@ -47,9 +55,10 @@ export default ExtendBase =>
return remote === true || (_.isObject(remote) && remote.search) || this.isRemotePagination();
}
- isRemotePagination = () => {
+ isRemotePagination = (e = {}) => {
const { remote } = this.props;
- return remote === true || (_.isObject(remote) && remote.pagination);
+ e.result = (remote === true || (_.isObject(remote) && remote.pagination));
+ return e.result;
}
isRemoteFiltering = () => {