UNPKG

@beisen/paging

Version:

configurable page component

658 lines (540 loc) 19 kB
/* 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;