Skip to content

【React】在ACE项目中封装了Pagination Component #43

@xinbaihui

Description

@xinbaihui

Add Pagination Component in ACE project (2019.08.18)

  1. keypress VS keydown
  • keypress: The keypress event is fired when a key is pressed down and that key normally produces a character value
  • keydown: 与 keypress事件不同的是,无论是否产生一个字符值,keydown事件均会被触发
  • eg: ctrl, shift不会产生字符, 只触发keydown,其他比如enter,space会产生字符,两个都触发
  • The implementation of the theory is not same in all browsers.

so 此处用keyPress合适

  1. input size
    定义空间初始大小,默认20。指的是input的大小能显示20个字符。

  2. 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.

  • e.target: 指向事件触发的元素
  • e.currentTarget: 指向事件绑定的元素
  1. use parseInt(xx, 10) instead of parseInt(xx)
    参考:https://devdocs.io/javascript/global_objects/parseint

  2. origin code

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);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions