通过下拉菜单进行自定义反应分页,选择返回其他“ -1”寻呼机页面

时间:2019-03-29 21:14:56

标签: reactjs pagination html-select

我是一个非常新的反应者,我遇到了分页/下拉选择问题。我有一个由example 1example 2组成的分页组件。我将下拉选择提取到其自己的组件中。

我可以选择分页页面,也可以选择下拉选项来更改分页寻呼机。

问题:如果我位于下拉菜单选项的最后一页,并且将下拉菜单选择更改为其他选项,则在分页传呼机的最前面会添加一个额外的“ -1”页面...

例如:初始页数选择为2,寻呼机显示第1-14页。将页数选择为10,转到最后一页。选择页数为2,传呼机将显示-1、1-14页。我不确定-1的来源,但是当我重复用例时,会显示更多的-1。

我以为问题是分页组件中的此部分,但是没有运气...

      // pager pages
      for (let i = startPage; i < groupCount + startPage; i++) {
        // console.log(startPage);
        if (i <= totalPages - 1) {
          pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i} id={i}>{i}</li>);
        }
      }

我已包含以下代码和一个gif of the bug。任何帮助您查看代码或指导我朝正确方向发展的帮助将不胜感激。预先感谢!

分页组件

function Pagination(props) {
  // get items from object
  const items = props.items;
  // get items count from items.total_count
  const itemsLength = items.length;
  // const [dataLength, setDataLength] = useState(props.itemsLength);
  const [pageCount, setPageCount] = useState(props.pageCount);
  // get total # of pages for pager
  const totalPages = Math.ceil(itemsLength/pageCount);

  const [currentPage, setCurrentPage] = useState(props.currentPage);
  const [groupCount, setGroupCount] = useState(props.groupCount);
  const [startPage, setStartPage] = useState(props.startPage);
  const [paging, setPaging] = useState({
    currentPage: '',
    pageCount: ''
  });

  const displayCountOptions = props.displayCountOptions ? (
    <DropDownSelect
      legend={props.viewOptionHelpText}
      options={props.viewOptions}
      defaultSelectedOption={0}
      selectionID={props.viewOptionID}
      changeFunc={e => confirmPageCount(e.target.value)}
      size={props.viewOptionSize}
      layout={props.viewOptionLayout}
    />
  ) : ('');

  function createPager(totalPages) {
    let pages = [];

    if (totalPages <= 10) {
      // previous
      pages.push(<li onClick={e => getPrev(currentPage)} className={currentPage === 1 ? styles.nomore : ""} key={0}>Prev</li>);
      // pager pages
      for (let i = 1; i <= totalPages; i++) {
        pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i}>{i}</li>);
      }
      // next
      pages.push(<li onClick={e => getNext(currentPage, totalPages)} className={currentPage === totalPages ? styles.nomore : ""} key={totalPages + 1}>Next</li>);
    } else {
      // previous
      pages.push(<li onClick={e => getPrev(currentPage)} className={currentPage === 1 ? styles.nomore : ""} key={0}>Prev</li>);
      // if startPage is greater than groupCount
      if (startPage > groupCount) {
        // set first page as 1
        pages.push(<li onClick={e => getPage(1)} className={currentPage === 1 ? styles.active : ""} key={1}>1</li>);
        // ellipsis ...
        pages.push(<li onClick={e => getPage(startPage - groupCount)} className={styles.ellipsis} key={-2}>···</li>);
      }
      // pager pages
      for (let i = startPage; i < groupCount + startPage; i++) {
        // console.log(startPage);
        if (i <= totalPages - 1) {
          pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i} id={i}>{i}</li>);
        }
      }
      // ellipsis ...
      if (totalPages - startPage > groupCount) {
        pages.push(<li onClick={e => getPage(startPage + groupCount)} className={styles.ellipsis} key={-1}>···</li>);
      }
      // last page
      pages.push(<li className={currentPage === totalPages ? styles.active : ""} key={totalPages} onClick={e => getPage(totalPages)}>{totalPages}</li>);
      // next
      pages.push(<li onClick={e => getNext(currentPage, totalPages)} className={currentPage === totalPages ? styles.nomore : ""} key={totalPages + 1}>Next</li>);
    }

    return pages;
  }

  function getPage(currentPage, reset = false) {
    setCurrentPage(currentPage);
    // console.log(currentPage);

    // handles getPage for prev page
    if (currentPage % groupCount === 1) {
      setStartPage(currentPage);
    }
    // handles getPage for next page
    if (currentPage % groupCount === 0) {
      setStartPage(currentPage - groupCount + 1);
    }
    // last page
    if (totalPages - currentPage < 1) {
      setStartPage(totalPages - groupCount);
    }

    if (reset === true) {
      setCurrentPage(1);
      setStartPage(1);
    }

    setTimeout(()=>{
      setPaging({
        currentPage: currentPage,
        pageCount: pageCount
      });
    });
    // console.log(paging);
  }

  function getPrev(currentPage) {
    if (--currentPage === 0) {
      return;
    }
    getPage(currentPage);
  }

  function getNext(currentPage) {
    if (++currentPage > totalPages) {
      return;
    }
    getPage(currentPage);
  }

  function confirmPageCount(pageCount){
    setPageCount(pageCount);
    console.log(pageCount);
    console.log(totalPages);
    setTimeout(()=>{
      getPage(currentPage, true);
    }, 0);
  }

  const [upperLimit, setUpperLimit] = useState(undefined);
  const [paginatedData, setPaginatedData] = useState([]);

  function createPaginatedData(pageCount) {
    setUpperLimit(currentPage * pageCount);
    const itemsSlice = items.slice((upperLimit - pageCount), upperLimit);
    setPaginatedData(itemsSlice);
  }

  useEffect(() => {
    createPaginatedData(pageCount);
  }), [pageCount];

  const pages = createPager(totalPages);

  return(
    <React.Fragment>
      <div className={styles.main}>
        {displayCountOptions}
        <ul className={styles.page}>
          {pages}
        </ul>
      </div>

      <div className='pagination-results'>
        {React.cloneElement(props.children, {items: paginatedData})}
      </div>
    </React.Fragment>
  );
}

DropDownSelect组件

function DropDownSelect(props) {
  // const { themeContext } = useContext(ThemeContext);
  const dropDownSelectGroup = cx({
    dropDownSelectGroup: true,
    [`${props.layout}`]: true,
    // [`${themeContext.theme}Theme`]: true
  });

  const dropDownSelections = cx({
    dropDownSelections: true
  });

  const selectionsUl = cx({
    [`${props.size}`]: true,
    hide: true
  });

  const [defaultOption, setDefaultOption] = useState(props.defaultSelectedOption);

  const [selected, setSelected] = useState(defaultOption);

  const [pageCountEle, setPageCountEle] = useState(undefined);

  function createLabel(item) {
    var splitItem = item.split(/[ ,]+/).filter(Boolean);
    var finalItem = splitItem.join('');
    return 'select' + finalItem;
  }

  const selectID = props.selectionID ? props.selectionID : '';

  useEffect(() => {
    setPageCountEle(document.querySelector(`#${selectID}`));
  });

  const legend = props.legend ? (
    <label htmlFor={createLabel(props.legend)} className={styles.helpText}>{props.legend}</label>
  ) : (
    ''
  );

  // props changefunc takes in a function and attach it to when drop down select value is changed
  function handleChange(e) {
    //if prevent default is false, use html submit, not this function
    if (!props.preventDefault) {
      return;
    }
    //stop html submit
    e.preventDefault();
    //execute the changeFunc function passed in via props
    props.changeFunc(e);
  }

  function changeOption(e) {
    // console.log(e.target);
    pageCountEle.innerHTML = e.target.innerHTML;
    pageCountEle.parentNode.className = selectionsUl;
    pageCountEle.parentNode.className += " " + styles.hide;
  }

  function chooseOption(e){
    // console.log(e);
    const parentUI = e.parentNode;
    // console.log(pageCountEle.parentNode);
    if (parentUI.classList.contains(styles.hide)) {
      parentUI.classList.remove(styles.hide);
    } else {
      parentUI.className += " " + styles.hide;
    }
  }

  const selections = props.options ? (
    <div className={dropDownSelections}>
      <ul
      className={selectionsUl}
      value={defaultOption}
      >
        <li
          id={selectID}
          onClick={e => chooseOption(e.target)}
          >{props.options[defaultOption].label}</li>
        {props.options.map((option, index) => {
          return <li id={option.value} key={index} value={option.value}
          onClick={e => {changeOption(e); handleChange(e);}}
          >{option.label}</li>
        })}
      </ul>
    </div>
  ) : (
    ''
  );

  return (
    <div className={dropDownSelectGroup}>
      {legend}
      {selections}
    </div>
  );
}

0 个答案:

没有答案