import * as React from 'react';
import { withStyles, WithStyles } from '@material-ui/core/styles';
import { compose } from 'recompose';
import ClrIcon from '../ClrIcon'
import styles from './styles';
interface PaginationProps extends WithStyles<typeof styles> {
className?: string;
pageSize?: number;
total?: number;
onPageNumberChange(pageNum: number): void;
}
interface PaginationState {
currentPageNum: number; // 1 ~ lastPageNum
inputValue: number; // 1 ~ lastPageNum
}
class Pagination extends React.PureComponent<PaginationProps, PaginationState> {
static defaultProps = {
pageSize: 10,
total: 0
};
state = {
currentPageNum: 1,
inputValue: 1
};
/**
*
* @param value current input value
*/
setInputValue(value) {
const currentInputValue = parseInt(value, 10)
const { currentPageNum, inputValue } = this.state;
// back to the current page when input value is not a number
if (isNaN(currentInputValue)) {
this.setState({
inputValue: currentPageNum
})
return
}
const { pageSize, total } = this.props;
const lastPageNum = Math.ceil(total / pageSize);
const newPageNum = Math.min(Math.max(currentInputValue, 1), lastPageNum);
if (newPageNum !== inputValue) {
this.setState({
inputValue: newPageNum
});
}
if (newPageNum !== currentPageNum) {
this.setState({
currentPageNum: newPageNum
});
this.props.onPageNumberChange(newPageNum);
}
}
/**
* handleChangeBtnClick
* @param pageNum new page number
*/
handlePageChangeBtnClick(pageNum: number) {
this.setState({
currentPageNum: pageNum,
inputValue: pageNum
});
this.props.onPageNumberChange(pageNum);
}
handleInputChange = e => {
this.setState({
inputValue: e.currentTarget.value // inputValue !== currentPageNum when change the input value while not press the input
});
}
handleInputPressEnter = e => {
if (e.key === 'Enter') {
this.setInputValue(e.currentTarget.value)
}
}
handleInputBlur = e => {
this.setInputValue(e.currentTarget.value)
}
render() {
const { pageSize, total } = this.props;
const { currentPageNum, inputValue } = this.state;
const lastPageNum = Math.ceil(total / pageSize);
const previousButtonDisabled = (currentPageNum === 1); // whether previous and first button disabled
const nextButtonDisabled = (currentPageNum === lastPageNum); // whether next and last button disabled
const firstShowItemIndex = (currentPageNum - 1) * pageSize + 1;
const lastShowItemIndex = Math.min(currentPageNum * pageSize, total);
const description = total ? `${firstShowItemIndex} - ${lastShowItemIndex} of ${total} items` : '0 items found';
return (
<div className="datagrid-footer">
<div className="pagination">
<span className="pagination-description">{description}</span>
{total ? <div className="pagination-list">
<button
className="pagination-first"
disabled={previousButtonDisabled} >
<ClrIcon
shape="step-forward-2 down"
size="2rem"
onClick={() => { this.handlePageChangeBtnClick(1); }}
/>
</button>
<button
className="pagination-previous"
disabled={previousButtonDisabled} >
<ClrIcon
shape="angle left"
size="2rem"
onClick={() => { this.handlePageChangeBtnClick(currentPageNum - 1); }}
/>
</button>
<input
type="text"
className="pagination-current"
size={4}
onChange={this.handleInputChange}
onKeyPress={this.handleInputPressEnter}
onBlur={this.handleInputBlur}
value={inputValue}
/>
<span>{`/ ${lastPageNum || 1}`}</span>
<button
className="pagination-next"
disabled={nextButtonDisabled}>
<ClrIcon
shape="angle right"
size="2rem"
onClick={() => { this.handlePageChangeBtnClick(currentPageNum + 1); }}
/>
</button>
<button
className="pagination-last"
disabled={nextButtonDisabled} >
<ClrIcon
shape="step-forward-2 up"
size="2rem"
onClick={() => { this.handlePageChangeBtnClick(lastPageNum); }}
/>
</button>
</div> : null}
</div>
</div>
);
}
}
export default compose(
withStyles(styles, {
withTheme: true
})
)(Pagination);
Add Pagination Component in ACE project (2019.08.18)
input size
定义空间初始大小,默认20。指的是input的大小能显示20个字符。
e.target VS e.currentTarget
e.target is what triggers the event dispatcher to trigger and e.currentTarget is what you assigned your listener to.
use parseInt(xx, 10) instead of parseInt(xx)
参考:https://devdocs.io/javascript/global_objects/parseint
origin code