Skip to main content

max / goingson

4.4 KB · 160 lines History Blame Raw
1 /**
2 * GoingsOn - Pagination Manager
3 * Generic pagination handling for lists.
4 * Replaces duplicate pagination code in tasks.js and emails.js.
5 */
6
7 (function() {
8 'use strict';
9
10 class PaginationManager {
11 /**
12 * Create a pagination manager.
13 * @param {string} type - Item type identifier (used for DOM element IDs)
14 * @param {number} itemsPerPage - Number of items per page
15 */
16 constructor(type, itemsPerPage = 25) {
17 this.type = type;
18 this.itemsPerPage = itemsPerPage;
19 this.currentPage = 1;
20 this.totalItems = 0;
21 }
22
23 /**
24 * Navigate to a page.
25 * @param {'prev'|'next'|number} direction - Direction or page number
26 * @returns {number} The new current page
27 */
28 goToPage(direction) {
29 const maxPage = this.getMaxPage();
30
31 if (direction === 'prev') {
32 this.currentPage = Math.max(1, this.currentPage - 1);
33 } else if (direction === 'next') {
34 this.currentPage = Math.min(maxPage, this.currentPage + 1);
35 } else if (typeof direction === 'number') {
36 this.currentPage = Math.max(1, Math.min(maxPage, direction));
37 }
38
39 return this.currentPage;
40 }
41
42 /**
43 * Get the current page number.
44 * @returns {number}
45 */
46 getCurrentPage() {
47 return this.currentPage;
48 }
49
50 /**
51 * Get the maximum page number.
52 * @returns {number}
53 */
54 getMaxPage() {
55 return Math.max(1, Math.ceil(this.totalItems / this.itemsPerPage));
56 }
57
58 /**
59 * Set the total number of items and validate current page.
60 * @param {number} total - Total number of items
61 */
62 setTotalItems(total) {
63 this.totalItems = total;
64 // Validate current page
65 const maxPage = this.getMaxPage();
66 if (this.currentPage > maxPage) {
67 this.currentPage = maxPage;
68 }
69 if (this.currentPage < 1) {
70 this.currentPage = 1;
71 }
72 }
73
74 /**
75 * Reset pagination to first page.
76 */
77 reset() {
78 this.currentPage = 1;
79 }
80
81 /**
82 * Get the offset for the current page (for backend pagination).
83 * @returns {number} The number of items to skip
84 */
85 getOffset() {
86 return (this.currentPage - 1) * this.itemsPerPage;
87 }
88
89 /**
90 * Get a paginated slice of items (for client-side pagination).
91 * @param {Array} items - All items
92 * @returns {Array} Paginated items
93 */
94 paginate(items) {
95 const start = this.getOffset();
96 return items.slice(start, start + this.itemsPerPage);
97 }
98
99 /**
100 * Update the pagination UI elements.
101 */
102 updateUI() {
103 const container = document.getElementById(`${this.type}-pagination`);
104 const prevBtn = document.getElementById(`${this.type}-prev-page`);
105 const nextBtn = document.getElementById(`${this.type}-next-page`);
106 const pageInfo = document.getElementById(`${this.type}-page-info`);
107
108 if (!container) return;
109
110 // Show/hide pagination
111 if (this.totalItems <= this.itemsPerPage) {
112 container.style.display = 'none';
113 return;
114 }
115
116 container.style.display = 'flex';
117
118 const maxPage = this.getMaxPage();
119
120 // Update buttons
121 if (prevBtn) prevBtn.disabled = this.currentPage <= 1;
122 if (nextBtn) nextBtn.disabled = this.currentPage >= maxPage;
123
124 // Update page info
125 if (pageInfo) {
126 const start = (this.currentPage - 1) * this.itemsPerPage + 1;
127 const end = Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
128 pageInfo.textContent = `${start}-${end} of ${this.totalItems} (Page ${this.currentPage}/${maxPage})`;
129 }
130 }
131
132 /**
133 * Get pagination info for display.
134 * @returns {Object} Pagination info
135 */
136 getInfo() {
137 const maxPage = this.getMaxPage();
138 const start = (this.currentPage - 1) * this.itemsPerPage + 1;
139 const end = Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
140
141 return {
142 currentPage: this.currentPage,
143 maxPage,
144 start,
145 end,
146 total: this.totalItems,
147 hasPrev: this.currentPage > 1,
148 hasNext: this.currentPage < maxPage
149 };
150 }
151 }
152
153 // ============ Populate GoingsOn Namespace ============
154
155 if (window.GoingsOn) {
156 GoingsOn.PaginationManager = PaginationManager;
157 }
158
159 })();
160