1 /**
2 * Copyright 2005-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.widget;
17
18 import org.kuali.rice.krad.uif.component.Component;
19 import org.kuali.rice.krad.uif.view.View;
20
21 /**
22 * The Pager widget is used to display a list of links horizontally in a page selection user interface. The user can
23 * select a page to jump to, go to prev/next page, or go to the first or last page. This widget needs to know
24 * the numberOfPages total, and the currentPage the user is on currently, so this widget must be fed this information
25 * from the code.
26 *
27 * @author Kuali Rice Team (rice.collab@kuali.org)
28 * @see org.kuali.rice.krad.uif.layout.StackedLayoutManager
29 */
30 public class Pager extends WidgetBase {
31 private String linkScript;
32 private int maxNumberedLinksShown;
33 private int numberOfPages;
34 private int currentPage;
35 private boolean renderPrevNext;
36 private boolean renderFirstLast;
37
38 protected int pagesStart;
39 protected int pagesEnd;
40
41 public Pager() {
42 super();
43 }
44
45 /**
46 * performFinalize calculates the pagesStart and pagesEnd properties (using numberOfPages, currentPage, and
47 * maxNumberedLinksShown - these must be set) which determines pages shown by the widget
48 *
49 * @param view the current view
50 * @param model the current model
51 * @param parent parent container
52 */
53 @Override
54 public void performFinalize(View view, Object model, Component parent) {
55 super.performFinalize(view, model, parent);
56
57 // if no pages or 1 page, do not render
58 if (numberOfPages == 0 || numberOfPages == 1) {
59 this.setRender(false);
60 }
61
62 if (maxNumberedLinksShown >= numberOfPages) {
63 // Show all pages if possible to do so
64 pagesStart = 1;
65 pagesEnd = numberOfPages;
66 } else {
67 // Determine how many pages max shown before an after the current page
68 int beforeAfterShown = (int) Math.floor((double) maxNumberedLinksShown / 2.0);
69 pagesStart = currentPage - beforeAfterShown;
70 pagesEnd = currentPage + beforeAfterShown;
71
72 // If maxNumberedLinksShown is even and cannot have an equal amount of pages showing before
73 // and after the current page, so trim one off the end
74 if (pagesEnd - pagesStart == maxNumberedLinksShown) {
75 pagesEnd = pagesEnd - 1;
76 }
77
78 // The pagesEnd is within range of numberOfPages total, therefore show the last pages
79 if (pagesEnd > numberOfPages) {
80 pagesEnd = numberOfPages;
81 pagesStart = numberOfPages - maxNumberedLinksShown + 1;
82 }
83
84 // The pageStart is within range, therefore show the first pages
85 if (pagesStart < 1) {
86 pagesStart = 1;
87 if (maxNumberedLinksShown < numberOfPages) {
88 pagesEnd = maxNumberedLinksShown;
89 }
90 }
91 }
92
93 this.linkScript = "e.preventDefault();" + this.linkScript;
94 }
95
96 /**
97 * The script to execute when a link is clicked (should probably use the "this" var in most cases, to determine
98 * page number selected - see retrieveStackedPage(linkElement, collectionId) js function)
99 *
100 * @return the script to execute when a link is clicked
101 */
102 public String getLinkScript() {
103 return linkScript;
104 }
105
106 /**
107 * Set the link js script
108 *
109 * @param linkScript the link js script
110 */
111 public void setLinkScript(String linkScript) {
112 this.linkScript = linkScript;
113 }
114
115 /**
116 * The maximum number of NUMBERED links shown at once for pages, if number of pages that exist exceed this value,
117 * the pager omits some pages before and/or after the current page (which are revealed during while
118 * navigating using a carousel effect)
119 *
120 * @return the maximum number of NUMBERED links to show
121 */
122 public int getMaxNumberedLinksShown() {
123 return maxNumberedLinksShown;
124 }
125
126 /**
127 * Set the maximum number of NUMBERED links shown
128 *
129 * @param maxNumberedLinksShown
130 */
131 public void setMaxNumberedLinksShown(int maxNumberedLinksShown) {
132 this.maxNumberedLinksShown = maxNumberedLinksShown;
133 }
134
135 /**
136 * Number of pages TOTAL that make up the component being paged (this must be set by the framework based on some
137 * list size)
138 *
139 * @return the number of pages used in this pager
140 */
141 public int getNumberOfPages() {
142 return numberOfPages;
143 }
144
145 /**
146 * Set the TOTAL number of pages
147 *
148 * @param numberOfPages
149 */
150 public void setNumberOfPages(int numberOfPages) {
151 this.numberOfPages = numberOfPages;
152 }
153
154 /**
155 * The current page being shown by this pager widget (this must be set when the page is changed)
156 *
157 * @return the current page being shown
158 */
159 public int getCurrentPage() {
160 return currentPage;
161 }
162
163 /**
164 * Set the current page
165 *
166 * @param currentPage
167 */
168 public void setCurrentPage(int currentPage) {
169 this.currentPage = currentPage;
170 }
171
172 /**
173 * Returns true if this pager widget is rendering the "First" and "Last" links
174 *
175 * @return true if rendering "First" and "Last" links
176 */
177 public boolean isRenderFirstLast() {
178 return renderFirstLast;
179 }
180
181 /**
182 * Set renderFirstLast
183 *
184 * @param renderFirstLast
185 */
186 public void setRenderFirstLast(boolean renderFirstLast) {
187 this.renderFirstLast = renderFirstLast;
188 }
189
190 /**
191 * Returns true if this pager widget is rendering the "Prev" and "Next" links
192 *
193 * @return true if rendering "First" and "Last" links
194 */
195 public boolean isRenderPrevNext() {
196 return renderPrevNext;
197 }
198
199 /**
200 * Set renderPrevNext
201 *
202 * @param renderPrevNext
203 */
204 public void setRenderPrevNext(boolean renderPrevNext) {
205 this.renderPrevNext = renderPrevNext;
206 }
207
208 /**
209 * The first page number to render; this is set by the framework
210 *
211 * @return
212 */
213 public int getPagesStart() {
214 return pagesStart;
215 }
216
217 /**
218 * The last page number to render; this is set by the framework
219 *
220 * @return
221 */
222 public int getPagesEnd() {
223 return pagesEnd;
224 }
225
226 /**
227 * @see org.kuali.rice.krad.uif.component.ComponentBase#copy()
228 */
229 @Override
230 protected <T> void copyProperties(T component) {
231 super.copyProperties(component);
232 Pager pagerCopy = (Pager) component;
233 pagerCopy.setLinkScript(this.getLinkScript());
234 pagerCopy.setMaxNumberedLinksShown(this.getMaxNumberedLinksShown());
235 pagerCopy.setNumberOfPages(this.getNumberOfPages());
236 pagerCopy.setCurrentPage(this.getCurrentPage());
237 pagerCopy.setRenderPrevNext(this.isRenderPrevNext());
238 pagerCopy.setRenderFirstLast(this.isRenderFirstLast());
239 pagerCopy.pagesStart = this.pagesStart;
240 pagerCopy.pagesEnd = this.pagesEnd;
241 }
242 }