implement remote pagination

This commit is contained in:
AllenFang 2017-12-02 15:45:57 +08:00
parent 47f86dff4a
commit f9abcf42f4
5 changed files with 74 additions and 20 deletions

View File

@ -17,17 +17,46 @@ const wrapperFactory = baseElement =>
this.handleChangePage = this.handleChangePage.bind(this); this.handleChangePage = this.handleChangePage.bind(this);
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this); this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
let currPage;
let currSizePerPage;
const options = props.pagination.options || {}; const options = props.pagination.options || {};
const currPage = options.pageStartIndex || Const.PAGE_START_INDEX;
const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST; const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
const currSizePerPage = typeof sizePerPageList[0] === 'object' ? sizePerPageList[0].value : sizePerPageList[0];
// 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.state = { currPage, currSizePerPage }; this.state = { currPage, currSizePerPage };
} }
isRemote() {
const { remote } = this.props;
return remote === true || (typeof remote === 'object' && remote.pagination);
}
handleChangePage(currPage) { handleChangePage(currPage) {
const { pagination: { options } } = this.props; const { currSizePerPage } = this.state;
const { pagination: { options }, onRemotePageChange } = this.props;
if (options.onPageChange) { if (options.onPageChange) {
options.onPageChange(currPage, this.state.currSizePerPage); options.onPageChange(currPage, currSizePerPage);
}
if (this.isRemote()) {
onRemotePageChange(currPage, currSizePerPage);
return;
} }
this.setState(() => { this.setState(() => {
return { return {
@ -37,10 +66,14 @@ const wrapperFactory = baseElement =>
} }
handleChangeSizePerPage(currSizePerPage, currPage) { handleChangeSizePerPage(currSizePerPage, currPage) {
const { pagination: { options } } = this.props; const { pagination: { options }, onRemotePageChange } = this.props;
if (options.onSizePerPageChange) { if (options.onSizePerPageChange) {
options.onSizePerPageChange(currSizePerPage, currPage); options.onSizePerPageChange(currSizePerPage, currPage);
} }
if (this.isRemote()) {
onRemotePageChange(currPage, currSizePerPage);
return;
}
this.setState(() => { this.setState(() => {
return { return {
currPage, currPage,
@ -60,25 +93,31 @@ const wrapperFactory = baseElement =>
Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage; Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ? const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage; Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
Const.PAGE_START_INDEX : options.pageStartIndex;
const data = this.isRemote() ?
this.props.data :
store.getByCurrPage(currPage, currSizePerPage, pageStartIndex);
const base = baseElement({ const base = baseElement({
...this.props, ...this.props,
key: 'table', key: 'table',
data: store.getByCurrPage(currPage, currSizePerPage) data
}); });
return [ return [
base, base,
<Pagination <Pagination
key="pagination" key="pagination"
dataSize={ this.props.store.getDataSize() } dataSize={ options.totalSize || store.getDataSize() }
currPage={ currPage } currPage={ currPage }
currSizePerPage={ currSizePerPage } currSizePerPage={ currSizePerPage }
onPageChange={ this.handleChangePage } onPageChange={ this.handleChangePage }
onSizePerPageChange={ this.handleChangeSizePerPage } onSizePerPageChange={ this.handleChangeSizePerPage }
sizePerPageList={ options.sizePerPageList || Const.SIZE_PER_PAGE_LIST } sizePerPageList={ options.sizePerPageList || Const.SIZE_PER_PAGE_LIST }
paginationSize={ options.paginationSize || Const.PAGINATION_SIZE } paginationSize={ options.paginationSize || Const.PAGINATION_SIZE }
pageStartIndex={ options.pageStartIndex || Const.PAGE_START_INDEX } pageStartIndex={ pageStartIndex }
withFirstAndLast={ withFirstAndLast } withFirstAndLast={ withFirstAndLast }
alwaysShowAllBtns={ alwaysShowAllBtns } alwaysShowAllBtns={ alwaysShowAllBtns }
hideSizePerPage={ hideSizePerPage } hideSizePerPage={ hideSizePerPage }

View File

@ -100,6 +100,9 @@ BootstrapTable.propTypes = {
keyField: PropTypes.string.isRequired, keyField: PropTypes.string.isRequired,
data: PropTypes.array.isRequired, data: PropTypes.array.isRequired,
columns: PropTypes.array.isRequired, columns: PropTypes.array.isRequired,
remote: PropTypes.oneOfType([PropTypes.bool, PropTypes.shape({
pagination: PropTypes.bool
})]),
store: PropTypes.object, store: PropTypes.object,
noDataIndication: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), noDataIndication: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
striped: PropTypes.bool, striped: PropTypes.bool,
@ -153,10 +156,12 @@ BootstrapTable.propTypes = {
defaultSorted: PropTypes.arrayOf(PropTypes.shape({ defaultSorted: PropTypes.arrayOf(PropTypes.shape({
dataField: PropTypes.string.isRequired, dataField: PropTypes.string.isRequired,
order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired
})) })),
onTableChange: PropTypes.func
}; };
BootstrapTable.defaultProps = { BootstrapTable.defaultProps = {
remote: false,
striped: false, striped: false,
bordered: true, bordered: true,
hover: false, hover: false,

View File

@ -18,12 +18,18 @@ const withDataStore = Base =>
super(props); super(props);
this.store = new Store(props); this.store = new Store(props);
this.handleUpdateCell = this.handleUpdateCell.bind(this); this.handleUpdateCell = this.handleUpdateCell.bind(this);
this.onRemotePageChange = this.onRemotePageChange.bind(this);
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
this.store.set(nextProps.data); this.store.set(nextProps.data);
} }
onRemotePageChange(page, sizePerPage) {
const newState = { page, sizePerPage };
this.props.onTableChange(newState);
}
handleUpdateCell(rowId, dataField, newValue) { handleUpdateCell(rowId, dataField, newValue) {
const { cellEdit } = this.props; const { cellEdit } = this.props;
// handle cell editing internal // handle cell editing internal
@ -66,7 +72,10 @@ const withDataStore = Base =>
} else if (this.props.columns.filter(col => col.sort).length > 0) { } else if (this.props.columns.filter(col => col.sort).length > 0) {
return wrapWithSort(baseProps); return wrapWithSort(baseProps);
} else if (this.props.pagination) { } else if (this.props.pagination) {
return wrapWithPagination(baseProps); return wrapWithPagination({
...baseProps,
onRemotePageChange: this.onRemotePageChange
});
} }
return React.createElement(Base, baseProps); return React.createElement(Base, baseProps);

View File

@ -40,14 +40,19 @@ export default class Store {
return this.data; return this.data;
} }
getByCurrPage(page, sizePerPage) { getByCurrPage(page, sizePerPage, pageStartIndex) {
const end = (page * sizePerPage) - 1; const getNormalizedPage = () => {
const offset = Math.abs(1 - pageStartIndex);
return page + offset;
};
const end = (getNormalizedPage() * sizePerPage) - 1;
const start = end - (sizePerPage - 1); const start = end - (sizePerPage - 1);
const dataSize = this.getDataSize();
const result = []; const result = [];
for (let i = start; i <= end; i += 1) { for (let i = start; i <= end; i += 1) {
result.push(this.data[i]); result.push(this.data[i]);
if (i + 1 === this.getDataSize()) break; if (i + 1 === dataSize) break;
} }
return result; return result;
} }

View File

@ -20,13 +20,9 @@ export const pureTable = props =>
React.createElement(BootstrapTable, { ...props }); React.createElement(BootstrapTable, { ...props });
export const wrapWithPagination = (props) => { export const wrapWithPagination = (props) => {
if (props.pagination) { const { wrapper } = props.pagination;
const { wrapper } = props.pagination; const PaginationBase = wrapper(pureTable);
const PaginationBase = wrapper(pureTable); return React.createElement(PaginationBase, { ...props });
return React.createElement(PaginationBase, { ...props });
}
return pureTable(props);
}; };
export const paginationElement = props => pureTable(props); export const paginationElement = props => pureTable(props);