@beisen/paging
Version:
configurable page component
658 lines (540 loc) • 19 kB
JavaScript
/* eslint-disable */
import React, {
Component
} from 'react'
import { transFormat } from '@beisen/common-func'
import DropDownButton from '@beisen/dropdown-button';
import '../src/index.scss'
const defaultTranslation = {
pieceOrPage: '{0}条/页',
jumpTo: '跳转至',
countPageTotal: '共{0}页'
}
class Paging extends Component {
constructor(props) {
super(props)
this.state = {
currentPage: props.currentPage || 1,
isFocus: false,
inputValue: '',
capacity: props.capacity,
visiblePages:7
};
this.icon_next= this.state.currentPage === this.props.total ? "pc-sys-Forward-disabled-svg" : "pc-sys-Forward-nomal-svg";
this.icon_prev= this.state.currentPage === 1 ? "pc-sys-backward-disabled-svg" : "pc-sys-backward-nomal-svg";
this.translation = Object.assign({}, defaultTranslation, props.translation);
this.pageClick = this.pageClick.bind(this);
this.onChange = this.onChange.bind(this);
this.addClass = this.addClass.bind(this);
this.removeClass = this.removeClass.bind(this);
this.ulListStyle = this.ulListStyle.bind(this);
this.renderPageItems = this.renderPageItems.bind(this);
this.pageContainerStyle = this.pageContainerStyle.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
}
componentDidUpdate(){
if (!this.props.hidden) {
let fawidth = this.refs.pagref.parentElement.clientWidth;
let pawidth = this.refs.pagref.clientWidth;
let totle = document.getElementsByClassName('total').length > 0?document.getElementsByClassName('total')[0].clientWidth:0;
let allchose = document.getElementsByClassName('checkAllAcrossPage').length > 0?document.getElementsByClassName('checkAllAcrossPage')[0].clientWidth:0;
if(fawidth - (totle+allchose+30) < pawidth){
switch(this.state.visiblePages){
case 7 :
this.setState({visiblePages:5})
break;
case 5:
this.setState({visiblePages:3})
break;
case 3:
break;
}
}
}
}
// 数据校验
verify(props) {
const {
total,
// visiblePages,
currentPage
} = props;
try {
if (total < 2) {
throw {
name: 'TypeError',
message: 'error total'
}
}
} catch (err) {
console.error(err);
}
try {
if (currentPage < 1 || currentPage > total) {
throw {
name: 'TypeError',
message: 'error currentPage'
}
}
} catch (err) {
console.error(err);
}
// 因为新的需求需要有visiblePages少于5的情况这里把这部分的验证取消
// try {
// if (visiblePages < 5 || visiblePages % 2 === 0) {
// throw {
// name: 'TypeError',
// message: 'error visiblePages'
// }
// }
// } catch (err) {
// console.error(err);
// }
}
// 渲染item 除开头和和结尾
renderPageItems() {
const {
total,
// visiblePages
} = this.props;
const { visiblePages } = this.state;
const {
currentPage
} = this.state;
let pageItems = [];
// let tempClassName;
// wuzhe----四位数时,添加类,改变宽度
// for (let i = 2; i < total; i++) {
// let tempClassName = currentPage === i ? 'active' : '';
// if (i >= 1000) {
// pageItems.push(<li key={i} className={tempClassName}><a href="javascript:void(0)" data-index={i} className="page_large">{i}</a></li>)
// } else {
// pageItems.push(<li key={i} className={tempClassName}><a href="javascript:void(0)" data-index={i}>{i}</a></li>)
// }
// }
//优化渲染,防止出几万个Dom节点
let showCount = (visiblePages - 2)/2
if(currentPage>=5 && total-currentPage >=3 && total>99) {
for(let i =currentPage-Math.floor(showCount);i<currentPage+Math.ceil(showCount);i++) {
this.getPageItem(pageItems, currentPage, i);
}
} else if(total-currentPage<5 && total>99) {
let fir = total-currentPage < 5 ? total-5 :currentPage-1
for(let i =fir;i<total+1;i++) {
this.getPageItem(pageItems, currentPage, i);
}
}else{
let all = total > 100 ? 100 : total
for (let i = 2; i < all+1; i++) {
this.getPageItem(pageItems, currentPage, i, total);
}
}
return pageItems;
}
getPageItem(pageItems, currentPage, i, total) {
let tempClassName = currentPage === i ? 'active' : '';
if (i >= 1000) {
let width = 34 + ((i + "").length - 4) * 4
pageItems.push(<li key={i} className={tempClassName}><a href="javascript:void(0)" data-index={i} style={{"padding": "3px","width": width+"px"}}>{i}</a></li>)
} else {
pageItems.push(<li key={i} className={tempClassName}><a href="javascript:void(0)" data-index={i}>{i}</a></li>)
}
}
// 渲染样式
pageContainerStyle() {
const {
total,
// visiblePages
} = this.props;
const {
currentPage,
visiblePages
} = this.state;
if (total <= visiblePages) {
return;
}
let styles = {},
// num = visiblePages - 4;
num = visiblePages;
let tempEll = this.showEllipsis();
// num = tempEll.isEllPrev ? num : num+1;
// num = tempEll.isEllNext ? num : num+1;
styles['overflow'] = 'hidden';
if (num == 1) {
if (currentPage >= 1000) {
styles['width'] = num * (33 + ((currentPage + "").length-4)*4) + 1;
} else {
styles['width'] = num * 26 + 1;
}
return styles;
};
// wuzhe----省略号在中间
if (tempEll.isEllPrev && tempEll.isEllNext) {
num = visiblePages - 2;
const maxNum = currentPage + (num - 1) / 2;
const minNum = currentPage - (num - 1) / 2;
if (maxNum < 1000) {
styles['width'] = num * 26 + num + 1;
} else if (minNum >= 1000) {
styles['width'] =num * (34 + ((currentPage + "").length-4)*4) + num + 1;
} else {
const largeNum = maxNum - 1000 + 1;
styles['width'] = largeNum * 34 + (num - largeNum) * 26 + num;
}
return styles;
}
// wuzhe----省略号在左边
if (tempEll.isEllPrev) {
num = visiblePages - 1;
if (total > 1000) {
const minNum = total - num;
if (minNum >= 1000) {
styles['width'] = num * (34 + ((currentPage + "").length-4)*4) + num + 1;
} else {
const largeNum = total - 1000;
styles['width'] = largeNum * 33 + (num - largeNum) * 26 + num - 1 + largeNum - 2;
};
} else {
styles['width'] = num * 26 + num + 1;
}
return styles;
}
// wuzhe----省略号在右边
if (tempEll.isEllNext) {
num = visiblePages - 1;
styles['width'] = num * 26 + num + 1;
return styles;
}
}
// ul 样式
ulListStyle() {
const {
total,
// visiblePages
} = this.props;
const { visiblePages } =this.state;
const preWidth = (1000 - 2) * 26;
if (total <= visiblePages) {
return;
}
let styles = {};
// wuzhe----
if (total > 1000) {
styles['width'] = (total - 1000) * 33 + preWidth + total - 1;
styles['marginRight'] = this.transformUl();
} else {
//去除最后一页,此处total-2,变为 total -1
styles['width'] = (total - 1) * 26 + total;
styles['marginRight'] = this.transformUl();
}
if (styles['marginRight']) {
styles['overflow'] = 'initial'
}
return styles;
}
// ul move
transformUl() {
const {
total,
// visiblePages
} = this.props;
const { visiblePages } = this.state;
const {
currentPage
} = this.state;
if (total <= visiblePages) {
return;
}
let tempEll = this.showEllipsis();
let translateX, largeNum;
// let num = visiblePages - 4;
let num = visiblePages;
// num = tempEll.isEllPrev ? num-1 : num;
// num = tempEll.isEllNext ? num-1 : num;
if (tempEll.isEllPrev && tempEll.isEllNext) {
//去除最后一页,此处total+2 变为 total +3
let count = ((total + 3) - (visiblePages + 1) / 2) - currentPage;
// wuzhe----
let moveNum = total - count;
if (total <= 1000) {
translateX = -((count-1) * 26 + count) + 1 + 'px';
} else if (moveNum >= 1000) {
translateX = -(33 * count + count + 1) + 'px';
} else {
largeNum = total - 1000;
translateX = -(33 * largeNum + largeNum + 1) - ((count - largeNum) * 34) + 'px';
}
return translateX;
}
if (tempEll.isEllPrev) {
let middle = (visiblePages + 1) / 2;
if (currentPage > (total - middle - 2)) {
return 0;
}
}
const preWidth = (1000 - 2) * 26;
if (tempEll.isEllNext) {
//去除最后一页,此处total-2 变为 total -1
// let count = (total - 1) - (visiblePages - 3);
let count = (total - 2) - (visiblePages - 1);
if (total > 1000) {
translateX = -((total - 1000) * 33 + preWidth + total - 1 - (num * 26 + num)) + 'px';
} else {
translateX = ((count + 1) * 26 + count + 1) * -1 + 'px';
}
return translateX;
}
}
// 是否显示省略号
showEllipsis() {
const {
total,
// visiblePages
} = this.props;
const { visiblePages } = this.state;
const {
currentPage
} = this.state;
let obj = {
isEllPrev: false,
isEllNext: false
};
if (total <= visiblePages) {
return obj;
}
const middle = (visiblePages + 1) / 2;
obj.isEllPrev = currentPage > middle ? true : false;
//去除最后一页,此处+1
obj.isEllNext = (total - currentPage +1 ) >= middle ? true : false;
return obj;
}
addClass(event) {
event.stopPropagation();
this.setState({
isFocus: true
});
this.props.focusCallBack && this.props.focusCallBack(event);
}
// input blur animation
removeClass(event) {
event.stopPropagation();
this.setState({
isFocus: false
});
this.props.blurCallBack && this.props.blurCallBack(event);
}
// input onchange event
onChange(event) {
this.setState({
inputValue: event.target.value
});
this.props.changeCallBack && this.props.changeCallBack(event);
}
// click
pageClick(event) {
if (event.target.className.indexOf('drop-down-btn-title') > -1) return;
if (event.target.className.indexOf('drop-down-btn-svg') > -1) return;
// event.stopPropagation(); // 影响了推屏关闭,暂时注掉,不知道为啥加的
let node = event.target;
if (this.props.total == 1) return;
if (node.tagName == 'DIV' || node.tagName == 'INPUT' || node.tagName == 'UL') return;
if (node.className === 'page-ellipsis') return;
let index;
if (node.className == 'goAnyWhere') {
index = this.paging_input.value;
if (parseInt(index) >= 1 && parseInt(index) <= this.props.total) {
if (parseInt(index) === this.state.currentPage) return;
this.state.inputValue = '';
} else {
return;
}
} else {
index = node.getAttribute('data-index');
if (parseInt(index) === this.state.currentPage) return;
}
this.state.currentPage = parseInt(index);
this.icon_next= this.state.currentPage === this.props.total ? "pc-sys-Forward-disabled-svg" : "pc-sys-Forward-nomal-svg";
this.icon_prev= this.state.currentPage === 1 ? "pc-sys-backward-disabled-svg" : "pc-sys-backward-nomal-svg";
this.setState(this.state);
this.props.onIndexChange && this.props.onIndexChange(parseInt(index));
}
//zyt
handleKeyUp(e) {
let index = this.paging_input.value;
if (e.keyCode==13&&parseInt(index) >= 1 && parseInt(index) <= this.props.total) {
if (parseInt(index) === this.state.currentPage) return;
this.state.inputValue = '';
} else {
return;
}
this.setState({currentPage: parseInt(index)});
this.props.onIndexChange && this.props.onIndexChange(parseInt(index));
}
dropDownClick(val,target,onClick,stateVal) {
target.stopPropagation();
this.state.capacity = parseInt(val.text);
this.setState(this.state);
this.props.onCapacityChange && this.props.onCapacityChange(val.value);
}
componentWillReceiveProps(nextProps) {
if (nextProps.currentPage != this.props.currentPage) {
this.setState({
currentPage: nextProps.currentPage
});
}
}
handleOver = (e) => {
console.log(e);
switch(e){
case 'icon_ne':
if(this.icon_next == 'pc-sys-Forward-nomal-svg'){
this.icon_next = 'pc-sys-Forward-active-svg'
this.setState({})
}
break;
case 'icon_pr':
console.log(this.icon_prev)
if(this.icon_prev == 'pc-sys-backward-nomal-svg'){
this.icon_prev = 'pc-sys-backward-active-svg'
this.setState({})
}
break;
}
}
handleLeave =(e)=> {
console.log(e);
switch(e){
case 'icon_ne':
if(this.icon_next == 'pc-sys-Forward-active-svg'){
this.icon_next = 'pc-sys-Forward-nomal-svg'
this.setState({})
}
break;
case 'icon_pr':
if(this.icon_prev == 'pc-sys-backward-active-svg'){
this.icon_prev = 'pc-sys-backward-nomal-svg'
this.setState({})
}
break;
}
}
render() {
const {
total,
hidden,
capacity,
capacityList,
isShowDropdown = true
} = this.props;
const {
currentPage,
inputValue,
isFocus
} = this.state;
if (!hidden) {
// 省略号显示
let tempEll = this.showEllipsis();
let ell_prev_style = tempEll.isEllPrev ? {
display: 'inline-block'
} : {
display: 'none'
};
let ell_next_style = tempEll.isEllNext ? {
display: 'inline-block'
} : {
display: 'none'
};
let start_temp = currentPage === 1 ? 'page_start active' : 'page_start';
let end_temp = currentPage === total ? 'page_end active' : 'page_end';
let end_style = {};
if (total >= 1000) {
end_temp += ' page_large';
if (total>= 10000) {
let width = 34 + ((total + "").length - 4) * 4
end_style = {"padding": "3px","width": width+"px"}
}
};
let nextPage = currentPage === total ? total : currentPage + 1;
let prevPage = currentPage === 1 ? 1 : currentPage - 1;
let notAllowed_prev = currentPage === 1 ? ' notAllowed_prev' : '';
let notAllowed_next = currentPage === total ? ' notAllowed_next' : '';
this.icon_prev = currentPage === 1 ? "pc-sys-backward-disabled-svg" : "pc-sys-backward-nomal-svg";
this.icon_next = currentPage === total ? "pc-sys-Forward-disabled-svg" : 'pc-sys-Forward-nomal-svg';
let dropChildren = capacityList && capacityList.map((item, index) => {
let isFalg = false;
if (capacity == item) isFalg = true;
return {
value: index,
text: transFormat(this.translation.pieceOrPage, item),
active: false,
isChecked: isFalg
}
});
let autoDirection = true;
let direction = 'right-down';
if (this.props.autoDirection !== undefined && this.props.direction !== undefined) {
autoDirection = this.props.autoDirection;
direction = this.props.direction;
}
let jumpTo = this.props.hasJumpTo ? (<div>
<a href="javascript:void(0)" className="goAnyWhere">Go</a>
<div className={"auto-rightinput auto-form-input " + inputClass}>
<input type="text" placeholder={this.translation.jumpTo} ref={(input) => {this.paging_input = input;}} value={inputValue} onClick={event => event.stopPropagation()} onKeyUp={this.handleKeyUp} onChange={this.onChange} onFocus={this.addClass} onBlur={this.removeClass} />
</div>
</div>
) : '';
let dropDownData = {
title: transFormat(this.translation.pieceOrPage, capacity),
type: 'text',
bsSize: 'small',
bsStyle: 'weaken',
children: dropChildren || [],
open: false,
iconName: "pc-sys-arrowdown-nomal-svg",
hoverName: "pc-sys-arrowdown-active-svg",
activeName: "pc-sys-arrowdown-active-svg",
direction: direction,
autoDirection: autoDirection,
onClick: this.dropDownClick.bind(this)
};
const inputClass = isFocus ? 'auto-form-input-active' : '';
const totalOne = total == 1 ? '' : <a href="javascript:void(0)" className={end_temp} style={end_style} data-index={total}>{total}</a>;
return (
<div className="paging" onClick={this.pageClick} ref = 'pagref'>
<div className="page-next">
<a className="page-ellipsis" style={ell_next_style}>...</a>
<a href="javascript:void(0)" onMouseOver={this.handleOver.bind(this,'icon_ne')} onMouseOut={this.handleLeave.bind(this,'icon_ne')} style={{"marginLeft": "4px"}} data-index={nextPage} className={this.icon_next + notAllowed_next + ' paging-icon paging__btn paging__btn__next'}></a>
{/* {totalOne} */}
{jumpTo}
</div>
<div className={
'page-container' +
( (total-currentPage<5 && total>99 || currentPage>=5 && total-currentPage >=3 && total>99)
? ''
:`${ell_prev_style.display == 'none' ? ' remove_left_radius' : ' add_left_radius'}`)
} style={this.pageContainerStyle()} >
<ul style={total > 99 ? {}:this.ulListStyle()}>
{this.renderPageItems()}
</ul>
</div>
<div className={'page-content' + `${ell_prev_style.display == 'none' ? '' : ' content-box'}`} >
<a className="page-ellipsis" style={ell_prev_style}>...</a>
<a href="javascript:void(0)" className={
start_temp +
`${ell_prev_style.display == 'none' && total != 1 ? ' remove_right_border remove_right_radius' : ''}`
} data-index="1">1</a>
<a href="javascript:void(0)" onMouseOver={this.handleOver.bind(this,'icon_pr')} onMouseOut={this.handleLeave.bind(this,'icon_pr')} data-index={prevPage} className={this.icon_prev + notAllowed_prev + ' paging-icon paging__btn'}></a>
{ isShowDropdown ? <DropDownButton {...dropDownData} /> : null }
{this.props.issum && this.props.issum == true?
<span style={{pointerEvents:"none"}} className='pag-sum'>{transFormat(this.translation.countPageTotal, total)}</span>
:''
}
</div>
</div>
)
} else {
return <div></div>
}
}
}
module.exports = Paging;