001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.element;
017
018import org.kuali.rice.krad.datadictionary.parse.BeanTag;
019import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
020import org.kuali.rice.krad.uif.util.LifecycleElement;
021
022/**
023 * The NumberedPager widget is used to display a list of links horizontally in a page selection user interface.
024 * The user can select a page to jump to, go to prev/next page, or go to the first or last page.  This widget needs to
025 * know the numberOfPages total, and the currentPage the user is on currently, so this widget must be fed this
026 * information from the code.
027 *
028 * @author Kuali Rice Team (rice.collab@kuali.org)
029 * @see org.kuali.rice.krad.uif.layout.StackedLayoutManager
030 */
031@BeanTag(name = "numberedPager", parent = "Uif-NumberedPager")
032public class NumberedPager extends Pager {
033    private static final long serialVersionUID = -6495003633052595157L;
034
035    private int maxNumberedLinksShown;
036    private boolean renderPrevNext;
037    private boolean renderFirstLast;
038
039    protected int pagesStart;
040    protected int pagesEnd;
041
042    private String firstText;
043    private String lastText;
044
045    /**
046     * performFinalize calculates the pagesStart and pagesEnd properties (using numberOfPages, currentPage, and
047     * maxNumberedLinksShown - these must be set) which determines pages shown by the widget
048     *
049     * @param model the current model
050     * @param parent parent container
051     */
052    @Override
053    public void performFinalize(Object model, LifecycleElement parent) {
054        super.performFinalize(model, parent);
055
056        if (maxNumberedLinksShown >= this.getNumberOfPages()) {
057            // Show all pages if possible to do so
058            pagesStart = 1;
059            pagesEnd = this.getNumberOfPages();
060        } else {
061            // Determine how many pages max shown before an after the current page
062            int beforeAfterShown = (int) Math.floor((double) maxNumberedLinksShown / 2.0);
063            pagesStart = this.getCurrentPage() - beforeAfterShown;
064            pagesEnd = this.getCurrentPage() + beforeAfterShown;
065
066            // If maxNumberedLinksShown is even and cannot have an equal amount of pages showing before
067            // and after the current page, so trim one off the end
068            if (pagesEnd - pagesStart == maxNumberedLinksShown) {
069                pagesEnd = pagesEnd - 1;
070            }
071
072            // The pagesEnd is within range of numberOfPages total, therefore show the last pages
073            if (pagesEnd > this.getNumberOfPages()) {
074                pagesEnd = this.getNumberOfPages();
075                pagesStart = this.getNumberOfPages() - maxNumberedLinksShown + 1;
076            }
077
078            // The pageStart is within range, therefore show the first pages
079            if (pagesStart < 1) {
080                pagesStart = 1;
081                if (maxNumberedLinksShown < this.getNumberOfPages()) {
082                    pagesEnd = maxNumberedLinksShown;
083                }
084            }
085        }
086    }
087
088    /**
089     * The maximum number of NUMBERED links shown at once for pages, if number of pages that exist exceed this value,
090     * the pager omits some pages before and/or after the current page (which are revealed during while
091     * navigating using a carousel effect)
092     *
093     * @return the maximum number of NUMBERED links to show
094     */
095    @BeanTagAttribute
096    public int getMaxNumberedLinksShown() {
097        return maxNumberedLinksShown;
098    }
099
100    /**
101     * Set the maximum number of NUMBERED links shown
102     *
103     * @param maxNumberedLinksShown
104     */
105    public void setMaxNumberedLinksShown(int maxNumberedLinksShown) {
106        this.maxNumberedLinksShown = maxNumberedLinksShown;
107    }
108
109    /**
110     * Returns true if this pager widget is rendering the "First" and "Last" links
111     *
112     * @return true if rendering "First" and "Last" links
113     */
114    @BeanTagAttribute
115    public boolean isRenderFirstLast() {
116        return renderFirstLast;
117    }
118
119    /**
120     * Set renderFirstLast
121     *
122     * @param renderFirstLast
123     */
124    public void setRenderFirstLast(boolean renderFirstLast) {
125        this.renderFirstLast = renderFirstLast;
126    }
127
128    /**
129     * Returns true if this pager widget is rendering the "Prev" and "Next" links
130     *
131     * @return true if rendering "First" and "Last" links
132     */
133    @BeanTagAttribute
134    public boolean isRenderPrevNext() {
135        return renderPrevNext;
136    }
137
138    /**
139     * Set renderPrevNext
140     *
141     * @param renderPrevNext
142     */
143    public void setRenderPrevNext(boolean renderPrevNext) {
144        this.renderPrevNext = renderPrevNext;
145    }
146
147    /**
148     * The first page number to render; this is set by the framework
149     *
150     * @return pages start
151     */
152    public int getPagesStart() {
153        return pagesStart;
154    }
155
156    /**
157     * The last page number to render; this is set by the framework
158     *
159     * @return last page number to render
160     */
161    public int getPagesEnd() {
162        return pagesEnd;
163    }
164
165    /**
166     * The text to use on the first link.
167     *
168     * @return the first link text
169     */
170    @BeanTagAttribute
171    public String getFirstText() {
172        return firstText;
173    }
174
175    /**
176     * @see NumberedPager#getFirstText()
177     */
178    public void setFirstText(String firstText) {
179        this.firstText = firstText;
180    }
181
182    /**
183     * The text to use for the last link.
184     *
185     * @return the last link text
186     */
187    @BeanTagAttribute
188    public String getLastText() {
189        return lastText;
190    }
191
192    /**
193     * @see NumberedPager#getLastText()
194     */
195    public void setLastText(String lastText) {
196        this.lastText = lastText;
197    }
198
199}