paginated_list.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS102: Remove unnecessary code created because of implicit returns
  6. * DS104: Avoid inline assignments
  7. * DS202: Simplify dynamic range loops
  8. * DS206: Consider reworking classes to avoid initClass
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  11. */
  12. (function () {
  13. let PER_PAGE = undefined;
  14. app.views.PaginatedList = class PaginatedList extends app.View {
  15. static initClass() {
  16. PER_PAGE = app.config.max_results;
  17. }
  18. constructor(data) {
  19. super();
  20. this.data = data;
  21. this.constructor.events = this.constructor.events || {};
  22. if (this.constructor.events.click == null) {
  23. this.constructor.events.click = "onClick";
  24. }
  25. }
  26. renderPaginated() {
  27. this.page = 0;
  28. if (this.totalPages() > 1) {
  29. this.paginateNext();
  30. } else {
  31. this.html(this.renderAll());
  32. }
  33. }
  34. // render: (dataSlice) -> implemented by subclass
  35. renderAll() {
  36. return this.render(this.data);
  37. }
  38. renderPage(page) {
  39. return this.render(
  40. this.data.slice((page - 1) * PER_PAGE, page * PER_PAGE),
  41. );
  42. }
  43. renderPageLink(count) {
  44. return this.tmpl("sidebarPageLink", count);
  45. }
  46. renderPrevLink(page) {
  47. return this.renderPageLink((page - 1) * PER_PAGE);
  48. }
  49. renderNextLink(page) {
  50. return this.renderPageLink(this.data.length - page * PER_PAGE);
  51. }
  52. totalPages() {
  53. return Math.ceil(this.data.length / PER_PAGE);
  54. }
  55. paginate(link) {
  56. $.lockScroll(link.nextSibling || link.previousSibling, () => {
  57. $.batchUpdate(this.el, () => {
  58. if (link.nextSibling) {
  59. this.paginatePrev(link);
  60. } else {
  61. this.paginateNext(link);
  62. }
  63. });
  64. });
  65. }
  66. paginateNext() {
  67. if (this.el.lastChild) {
  68. this.remove(this.el.lastChild);
  69. } // remove link
  70. if (this.page >= 2) {
  71. this.hideTopPage();
  72. } // keep previous page into view
  73. this.page++;
  74. this.append(this.renderPage(this.page));
  75. if (this.page < this.totalPages()) {
  76. this.append(this.renderNextLink(this.page));
  77. }
  78. }
  79. paginatePrev() {
  80. this.remove(this.el.firstChild); // remove link
  81. this.hideBottomPage();
  82. this.page--;
  83. this.prepend(this.renderPage(this.page - 1)); // previous page is offset by one
  84. if (this.page >= 3) {
  85. this.prepend(this.renderPrevLink(this.page - 1));
  86. }
  87. }
  88. paginateTo(object) {
  89. const index = this.data.indexOf(object);
  90. if (index >= PER_PAGE) {
  91. for (
  92. let i = 0, end = Math.floor(index / PER_PAGE), asc = 0 <= end;
  93. asc ? i < end : i > end;
  94. asc ? i++ : i--
  95. ) {
  96. this.paginateNext();
  97. }
  98. }
  99. }
  100. hideTopPage() {
  101. const n = this.page <= 2 ? PER_PAGE : PER_PAGE + 1; // remove link
  102. for (
  103. let i = 0, end = n, asc = 0 <= end;
  104. asc ? i < end : i > end;
  105. asc ? i++ : i--
  106. ) {
  107. this.remove(this.el.firstChild);
  108. }
  109. this.prepend(this.renderPrevLink(this.page));
  110. }
  111. hideBottomPage() {
  112. const n =
  113. this.page === this.totalPages()
  114. ? this.data.length % PER_PAGE || PER_PAGE
  115. : PER_PAGE + 1; // remove link
  116. for (
  117. let i = 0, end = n, asc = 0 <= end;
  118. asc ? i < end : i > end;
  119. asc ? i++ : i--
  120. ) {
  121. this.remove(this.el.lastChild);
  122. }
  123. this.append(this.renderNextLink(this.page - 1));
  124. }
  125. onClick(event) {
  126. const target = $.eventTarget(event);
  127. if (target.tagName === "SPAN") {
  128. // link
  129. $.stopEvent(event);
  130. this.paginate(target);
  131. }
  132. }
  133. };
  134. app.views.PaginatedList.initClass();
  135. return app.views.PaginatedList;
  136. })();