IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.7KB

  1. //
  2. // Copyright (C) Stanislaw Adaszewski, 2020
  3. // Contact: s.adaszewski@gmail.com
  4. // Website: https://adared.ch/wba
  5. // License: GNU Affero General Public License, Version 3
  6. //
  7. import { h, Component } from 'preact';
  8. class WBPagination extends Component {
  9. renderVisiblePages(numPages, activePage, chunkSize, onPageChanged, getPageUrl) {
  10. let visible = {};
  11. let begActChnk = activePage - Math.floor(chunkSize / 2);
  12. let endActChnk = activePage + Math.floor(chunkSize / 2) + 1;
  13. for (let i = Math.max(0, begActChnk); i < Math.min(numPages, endActChnk); i++)
  14. visible[i] = true;
  15. for (let i = 0; i < Math.min(numPages, chunkSize); i++)
  16. visible[i] = true;
  17. for (let i = Math.max(numPages - chunkSize, 0); i < numPages; i++)
  18. visible[i] = true;
  19. visible = Object.keys(visible).map(n => Number(n));
  20. visible.sort((a, b) => (a - b));
  21. let res = [];
  22. let prev = 0;
  23. res.push((
  24. <li class={ activePage === 0 ? "page-item disabled" : "page-item" }>
  25. <a class="page-link" href={ getPageUrl(activePage - 1) }
  26. onclick={ e => this.changePage(e, activePage - 1) }>Previous</a>
  27. </li>
  28. ));
  29. for (let idx = 0; idx < visible.length; idx++) {
  30. let i = visible[idx];
  31. let capturePrev = prev;
  32. if (i > prev + 1)
  33. res.push((
  34. <li class="page-item">
  35. <a class="page-link" href={ getPageUrl(Math.round((i + capturePrev) / 2)) }
  36. onclick={ e => this.changePage(e, Math.round((i + capturePrev) / 2)) }>...</a>
  37. </li>
  38. ));
  39. prev = i;
  40. res.push((
  41. <li class={ i === activePage ? "page-item active" : "page-item" }>
  42. <a class="page-link" href={ getPageUrl(i) }
  43. onclick={ e => this.changePage(e, i) }>{ i + 1 }</a>
  44. </li>
  45. ));
  46. }
  47. res.push((
  48. <li class={ activePage >= numPages - 1 ? "page-item disabled" : "page-item" }>
  49. <a class="page-link" href={ getPageUrl(activePage + 1) }
  50. onclick={ e => this.changePage(e, activePage + 1) }>Next</a>
  51. </li>
  52. ));
  53. return res;
  54. }
  55. changePage(e, pageIdx) {
  56. if (this.props.onPageChanged) {
  57. e.preventDefault();
  58. this.props.onPageChanged(pageIdx);
  59. }
  60. }
  61. render({ numPages, activePage, chunkSize, onPageChanged, getPageUrl }) {
  62. return (
  63. <nav aria-label="Pagination">
  64. <ul class="pagination">
  65. { this.renderVisiblePages(numPages, activePage, chunkSize, onPageChanged, getPageUrl) }
  66. </ul>
  67. </nav>
  68. );
  69. }
  70. }
  71. WBPagination.defaultProps = {
  72. 'chunkSize': 5,
  73. 'getPageUrl': () => ('#')
  74. };
  75. export default WBPagination;