mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-07-05 00:20:06 +00:00
implement pagination context
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import wrapperFactory from './src/wrapper';
|
||||
import createContext from './src/context';
|
||||
|
||||
export default (options = {}) => ({
|
||||
wrapperFactory,
|
||||
createContext,
|
||||
options
|
||||
});
|
||||
|
||||
@@ -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 [
|
||||
<Base key="table" { ...this.props } data={ data } />,
|
||||
<Pagination
|
||||
key="pagination"
|
||||
dataSize={ options.totalSize || store.data.length }
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
onPageChange={ this.handleChangePage }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
sizePerPageList={ options.sizePerPageList || Const.SIZE_PER_PAGE_LIST }
|
||||
paginationSize={ options.paginationSize || Const.PAGINATION_SIZE }
|
||||
pageStartIndex={ pageStartIndex }
|
||||
withFirstAndLast={ withFirstAndLast }
|
||||
alwaysShowAllBtns={ alwaysShowAllBtns }
|
||||
hideSizePerPage={ hideSizePerPage }
|
||||
hidePageListOnlyOnePage={ hidePageListOnlyOnePage }
|
||||
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 }
|
||||
/>
|
||||
];
|
||||
return (
|
||||
<PaginationContext.Provider value={ { data } }>
|
||||
{ this.props.children }
|
||||
<Pagination
|
||||
key="pagination"
|
||||
dataSize={ options.totalSize || this.props.data.length }
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
onPageChange={ this.handleChangePage }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
sizePerPageList={ options.sizePerPageList || Const.SIZE_PER_PAGE_LIST }
|
||||
paginationSize={ options.paginationSize || Const.PAGINATION_SIZE }
|
||||
pageStartIndex={ pageStartIndex }
|
||||
withFirstAndLast={ withFirstAndLast }
|
||||
alwaysShowAllBtns={ alwaysShowAllBtns }
|
||||
hideSizePerPage={ hideSizePerPage }
|
||||
hidePageListOnlyOnePage={ hidePageListOnlyOnePage }
|
||||
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 }
|
||||
/>
|
||||
</PaginationContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
Provider: PaginationProvider,
|
||||
Consumer: PaginationContext.Consumer
|
||||
};
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
) => (
|
||||
<Base
|
||||
@@ -59,7 +66,8 @@ const withContext = (Base) => {
|
||||
{ ...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
|
||||
) => (
|
||||
<SelectionContext.Provider
|
||||
{ ...baseProps }
|
||||
selectRow={ this.props.selectRow }
|
||||
data={ rootProps.getData(filterProps, sortProps) }
|
||||
data={ rootProps.getData(filterProps, sortProps, paginationProps) }
|
||||
>
|
||||
<SelectionContext.Consumer>
|
||||
{
|
||||
@@ -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
|
||||
) => (
|
||||
<PaginationContext.Provider
|
||||
ref={ n => this.paginationContext = n }
|
||||
pagination={ this.props.pagination }
|
||||
data={ rootProps.getData(filterProps, sortProps) }
|
||||
>
|
||||
<PaginationContext.Consumer>
|
||||
{
|
||||
paginationProps => base(
|
||||
rootProps,
|
||||
cellEditProps,
|
||||
filterProps,
|
||||
sortProps,
|
||||
paginationProps
|
||||
)
|
||||
}
|
||||
</PaginationContext.Consumer>
|
||||
</PaginationContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user