diff --git a/packages/react-bootstrap-table2-paginator/index.js b/packages/react-bootstrap-table2-paginator/index.js index edd0067..8750183 100644 --- a/packages/react-bootstrap-table2-paginator/index.js +++ b/packages/react-bootstrap-table2-paginator/index.js @@ -1,6 +1,6 @@ -import wrapperFactory from './src/wrapper'; +import createContext from './src/context'; export default (options = {}) => ({ - wrapperFactory, + createContext, options }); diff --git a/packages/react-bootstrap-table2-paginator/src/wrapper.js b/packages/react-bootstrap-table2-paginator/src/context.js similarity index 50% rename from packages/react-bootstrap-table2-paginator/src/wrapper.js rename to packages/react-bootstrap-table2-paginator/src/context.js index 784687a..2a60d14 100644 --- a/packages/react-bootstrap-table2-paginator/src/wrapper.js +++ b/packages/react-bootstrap-table2-paginator/src/context.js @@ -1,17 +1,21 @@ /* eslint react/prop-types: 0 */ -import React, { Component } from 'react'; +/* eslint react/require-default-props: 0 */ +import React from 'react'; import PropTypes from 'prop-types'; import Const from './const'; import Pagination from './pagination'; import { getByCurrPage, alignPage } from './page'; -export default (Base, { - remoteResolver -}) => - class PaginationWrapper extends remoteResolver(Component) { +export default ( + isRemotePagination, + handleRemotePageChange +) => { + const PaginationContext = React.createContext(); + + class PaginationProvider extends React.Component { static propTypes = { - store: PropTypes.object.isRequired + data: PropTypes.array.isRequired } constructor(props) { @@ -42,13 +46,13 @@ export default (Base, { currSizePerPage = sizePerPageList[0]; } - this.state = { currPage, currSizePerPage }; - this.saveToStore(currPage, currSizePerPage); + this.currPage = currPage; + this.currSizePerPage = currSizePerPage; } componentWillReceiveProps(nextProps) { let needNewState = false; - let { currPage, currSizePerPage } = this.state; + let { currPage, currSizePerPage } = this; const { page, sizePerPage, onPageChange } = nextProps.pagination.options; const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ? @@ -57,70 +61,64 @@ export default (Base, { if (typeof page !== 'undefined' && currPage !== page) { // user defined page currPage = page; needNewState = true; - } else if (nextProps.isDataChanged) { - currPage = alignPage(this.props.store, pageStartIndex, currSizePerPage); + } else { + currPage = alignPage(nextProps.data, currPage, currSizePerPage, pageStartIndex); needNewState = true; } - if (typeof currPage === 'undefined') { - currPage = pageStartIndex; - } - - if (typeof sizePerPage !== 'undefined') { + if (typeof sizePerPage !== 'undefined' && currSizePerPage !== sizePerPage) { currSizePerPage = sizePerPage; needNewState = true; } - this.saveToStore(currPage, currSizePerPage); - if (needNewState) { if (onPageChange) { onPageChange(currPage, currSizePerPage); } - this.setState(() => ({ currPage, currSizePerPage })); + + this.currPage = currPage; + this.currSizePerPage = currSizePerPage; } } - saveToStore(page, sizePerPage) { - this.props.store.page = page; - this.props.store.sizePerPage = sizePerPage; - } - handleChangePage(currPage) { - const { currSizePerPage } = this.state; + const { currSizePerPage } = this; const { pagination: { options } } = this.props; - this.saveToStore(currPage, currSizePerPage); if (options.onPageChange) { options.onPageChange(currPage, currSizePerPage); } - if (this.isRemotePagination()) { - this.handleRemotePageChange(); + + this.currPage = currPage; + + if (isRemotePagination()) { + handleRemotePageChange(currPage, currSizePerPage); return; } - this.setState(() => ({ currPage })); + this.forceUpdate(); } handleChangeSizePerPage(currSizePerPage, currPage) { const { pagination: { options } } = this.props; - this.saveToStore(currPage, currSizePerPage); if (options.onSizePerPageChange) { options.onSizePerPageChange(currSizePerPage, currPage); } - if (this.isRemotePagination()) { - this.handleRemotePageChange(); + + this.currPage = currPage; + this.currSizePerPage = currSizePerPage; + + if (isRemotePagination()) { + handleRemotePageChange(currPage, currSizePerPage); return; } - this.setState(() => ({ - currPage, - currSizePerPage - })); + this.forceUpdate(); } render() { - const { pagination: { options }, store } = this.props; - const { currPage, currSizePerPage } = this.state; + let { data } = this.props; + const { pagination: { options } } = 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' ? @@ -132,37 +130,50 @@ export default (Base, { const pageStartIndex = typeof options.pageStartIndex === 'undefined' ? Const.PAGE_START_INDEX : options.pageStartIndex; - const data = this.isRemotePagination() ? - this.props.data : - getByCurrPage(store, pageStartIndex); + data = isRemotePagination() ? + data : + getByCurrPage( + data, + currPage, + currSizePerPage, + pageStartIndex + ); - return [ - , - - ]; + return ( + + { this.props.children } + + + ); } + } + + return { + Provider: PaginationProvider, + Consumer: PaginationContext.Consumer }; +}; diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js index 3a9b863..40d2a8a 100644 --- a/packages/react-bootstrap-table2-paginator/src/page.js +++ b/packages/react-bootstrap-table2-paginator/src/page.js @@ -1,5 +1,3 @@ -/* eslint no-param-reassign: 0 */ - const getNormalizedPage = ( page, pageStartIndex @@ -19,25 +17,36 @@ const startIndex = ( sizePerPage, ) => end - (sizePerPage - 1); -export const alignPage = (store, pageStartIndex, sizePerPage) => { - const end = endIndex(store.page, sizePerPage, pageStartIndex); - const dataSize = store.data.length; +export const alignPage = ( + data, + page, + sizePerPage, + pageStartIndex +) => { + const end = endIndex(page, sizePerPage, pageStartIndex); + const dataSize = data.length; if (end - 1 > dataSize) { return pageStartIndex; } - return store.page; + return page; }; -export const getByCurrPage = (store, pageStartIndex) => { - const dataSize = store.data.length; +export const getByCurrPage = ( + data, + page, + sizePerPage, + pageStartIndex +) => { + const dataSize = data.length; if (!dataSize) return []; - const end = endIndex(store.page, store.sizePerPage, pageStartIndex); - const start = startIndex(end, store.sizePerPage); + + const end = endIndex(page, sizePerPage, pageStartIndex); + const start = startIndex(end, sizePerPage); const result = []; for (let i = start; i <= end; i += 1) { - result.push(store.data[i]); + result.push(data[i]); if (i + 1 === dataSize) break; } return result; diff --git a/packages/react-bootstrap-table2/src/contexts/data-context.js b/packages/react-bootstrap-table2/src/contexts/data-context.js index 5e34a84..8452509 100644 --- a/packages/react-bootstrap-table2/src/contexts/data-context.js +++ b/packages/react-bootstrap-table2/src/contexts/data-context.js @@ -16,8 +16,9 @@ export default () => { this.setState(() => ({ data: nextProps.data })); } - getData = (filterProps, sortProps) => { - if (sortProps) return sortProps.data; + getData = (filterProps, sortProps, paginationProps) => { + if (paginationProps) return paginationProps.data; + else if (sortProps) return sortProps.data; else if (filterProps) return filterProps.data; return this.props.data; } diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index 37562f4..3d6e644 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -14,6 +14,7 @@ const withContext = (Base) => { let CellEditContext; let SortContext; let FilterContext; + let PaginationContext; return class BootstrapTableContainer extends remoteResolver(Component) { constructor(props) { @@ -37,6 +38,11 @@ const withContext = (Base) => { FilterContext = props.filter.createContext( _, this.isRemoteFiltering, this.handleRemoteFilterChange); } + + if (props.pagination) { + PaginationContext = props.pagination.createContext( + this.isRemotePagination, this.handleRemotePageChange); + } } componentWillReceiveProps(nextProps) { @@ -51,6 +57,7 @@ const withContext = (Base) => { cellEditProps, filterProps, sortProps, + paginationProps, selectionProps ) => ( { { ...sortProps } { ...cellEditProps } { ...filterProps } - data={ rootProps.getData(filterProps, sortProps) } + { ...paginationProps } + data={ rootProps.getData(filterProps, sortProps, paginationProps) } /> ); } @@ -69,12 +77,13 @@ const withContext = (Base) => { rootProps, cellEditProps, filterProps, - sortProps + sortProps, + paginationProps ) => ( { @@ -83,6 +92,7 @@ const withContext = (Base) => { cellEditProps, filterProps, sortProps, + paginationProps, selectionProps ) } @@ -91,6 +101,33 @@ const withContext = (Base) => { ); } + renderWithPaginationCtx(base) { + return ( + rootProps, + cellEditProps, + filterProps, + sortProps + ) => ( + this.paginationContext = n } + pagination={ this.props.pagination } + data={ rootProps.getData(filterProps, sortProps) } + > + + { + paginationProps => base( + rootProps, + cellEditProps, + filterProps, + sortProps, + paginationProps + ) + } + + + ); + } + renderWithSortCtx(base, baseProps) { return ( rootProps, @@ -167,6 +204,10 @@ const withContext = (Base) => { base = this.renderWithSelectionCtx(base, baseProps); } + if (PaginationContext) { + base = this.renderWithPaginationCtx(base, baseProps); + } + if (SortContext) { base = this.renderWithSortCtx(base, baseProps); } 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 a6c94f6..f0470f4 100644 --- a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js +++ b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js @@ -2,30 +2,41 @@ import _ from '../utils'; export default ExtendBase => class RemoteResolver extends ExtendBase { - /* eslint class-methods-use-this: 0 */ getNewestState = (state = {}) => { - // const store = this.store || this.props.store; - // return { - // page: store.page, - // sizePerPage: store.sizePerPage, - // filters: store.filters, - // sortField: store.sortField, - // sortOrder: store.sortOrder, - // data: store.getAllData(), - // ...state - // }; - return { - sortOrder: this.sortContext.state.sortOrder, - sortField: this.sortContext.state.sortColumn ? + let sortOrder; + let sortField; + let page; + let sizePerPage; + let filters = {}; + + if (this.sortContext) { + sortOrder = this.sortContext.state.sortOrder; + sortField = this.sortContext.state.sortColumn ? this.sortContext.state.sortColumn.dataField : - null, - filters: this.filterContext ? this.filterContext.currFilters : {}, + null; + } + + if (this.filterContext) { + filters = this.filterContext.currFilters; + } + + if (this.paginationContext) { + page = this.paginationContext.currPage; + sizePerPage = this.paginationContext.currSizePerPage; + } + + return { + sortOrder, + sortField, + filters, + page, + sizePerPage, ...state, data: this.props.data }; } - isRemotePagination() { + isRemotePagination = () => { const { remote } = this.props; return remote === true || (_.isObject(remote) && remote.pagination); } @@ -45,8 +56,8 @@ export default ExtendBase => return remote === true || (_.isObject(remote) && remote.cellEdit); } - handleRemotePageChange() { - this.props.onTableChange('pagination', this.getNewestState()); + handleRemotePageChange = (page, sizePerPage) => { + this.props.onTableChange('pagination', this.getNewestState({ page, sizePerPage })); } handleRemoteFilterChange = (filters) => {