Skip to content

Instantly share code, notes, and snippets.

@TimNZ
Last active October 12, 2021 15:20
Show Gist options
  • Save TimNZ/83631516f3e7a1ca1be33228bc3d56d6 to your computer and use it in GitHub Desktop.
Save TimNZ/83631516f3e7a1ca1be33228bc3d56d6 to your computer and use it in GitHub Desktop.
Custom PaginationComponent for React Table when it is not practical to know total # of pages
/**
* Override React Table pagination component to be able to control Previous/Next
*/
import React, { Component } from 'react'
import classnames from 'classnames'
const defaultButton = props => (
<button type="button" {...props} className="-btn">
{props.children}
</button>
)
export default class ReactTablePagination extends Component {
constructor (props) {
super()
this.getSafePage = this.getSafePage.bind(this)
this.changePage = this.changePage.bind(this)
this.applyPage = this.applyPage.bind(this)
this.state = {
page: props.page,
}
}
componentWillReceiveProps (nextProps) {
this.setState({ page: nextProps.page })
}
getSafePage (page) {
if (isNaN(page)) {
page = this.props.page
}
if (this.props.canNextFromData)
return page
return Math.min(Math.max(page, 0), this.props.pages - 1)
}
changePage (page) {
page = this.getSafePage(page)
this.setState({ page })
if (this.props.page !== page) {
this.props.onPageChange(page)
}
}
applyPage (e) {
if (e) { e.preventDefault() }
const page = this.state.page
this.changePage(page === '' ? this.props.page : page)
}
render () {
const {
// Computed
pages,
// Props
page,
showPageSizeOptions,
pageSizeOptions,
pageSize,
data,
showPageJump,
canPrevious,
canNextFromData,
onPageSizeChange,
className,
PreviousComponent = defaultButton,
NextComponent = defaultButton,
showTotalPages = true
} = this.props
const canNext = this.props.canNextFromData
? data && data.length == pageSize
: this.props.canNext
return (
<div
className={classnames(className, '-pagination')}
style={this.props.style}
>
<div className="-previous">
<PreviousComponent
onClick={() => {
if (!canPrevious) return
this.changePage(page - 1)
}}
disabled={!canPrevious}
>
{this.props.previousText}
</PreviousComponent>
</div>
<div className="-center">
<span className="-pageInfo">
{this.props.pageText}{' '}
{showPageJump
? <div className="-pageJump">
<input
type={this.state.page === '' ? 'text' : 'number'}
onChange={e => {
const val = e.target.value
const page = val - 1
if (val === '') {
return this.setState({ page: val })
}
this.setState({ page: this.getSafePage(page) })
}}
value={this.state.page === '' ? '' : this.state.page + 1}
onBlur={this.applyPage}
onKeyPress={e => {
if (e.which === 13 || e.keyCode === 13) {
this.applyPage()
}
}}
/>
</div>
: <span className="-currentPage">
{page + 1}
</span>}{' '}
{showTotalPages
?
<React.Fragment>
{this.props.ofText}{' '}
<span className="-totalPages">{pages || 1}</span>
</React.Fragment>
: null}
</span>
{showPageSizeOptions &&
<span className="select-wrap -pageSizeOptions">
<select
onChange={e => onPageSizeChange(Number(e.target.value))}
value={pageSize}
>
{pageSizeOptions.map((option, i) => (
// eslint-disable-next-line react/no-array-index-key
<option key={i} value={option}>
{option} {this.props.rowsText}
</option>
))}
</select>
</span>}
</div>
<div className="-next">
<NextComponent
onClick={() => {
if (!canNext) return
this.changePage(page + 1)
}}
disabled={!canNext}
>
{this.props.nextText}
</NextComponent>
</div>
</div>
)
}
}
@TimNZ
Copy link
Author

TimNZ commented May 5, 2018

For many storage systems getting a record count is impractical or a hassle, in a performant way.

This custom PaginationComponent for https://github.com/react-tools/react-table supports a couple of new props:

  • canNextFromData (default = false) - canNext is determined from whether data.length == pageSize
  • showTotalPages (default = true) - display total # of pages

@TimNZ
Copy link
Author

TimNZ commented May 5, 2018

Usage:

import CustomPaginationComponent from './CustomPaginationComponent'

<ReactTable
   PaginationComponent={CustomPaginationComponent}
   showTotalPages={false}
   canNextFromData={true}
   ...
/>

@TimNZ
Copy link
Author

TimNZ commented May 20, 2019

License: MIT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment