View Javadoc

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.container;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21  import org.kuali.rice.krad.datadictionary.parse.BeanTags;
22  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23  import org.kuali.rice.krad.uif.UifConstants;
24  import org.kuali.rice.krad.uif.component.Component;
25  import org.kuali.rice.krad.uif.util.BreadcrumbItem;
26  import org.kuali.rice.krad.uif.util.BreadcrumbOptions;
27  import org.kuali.rice.krad.uif.util.PageBreadcrumbOptions;
28  import org.kuali.rice.krad.uif.view.FormView;
29  import org.kuali.rice.krad.uif.view.View;
30  import org.kuali.rice.krad.web.form.UifFormBase;
31  
32  import java.util.ArrayList;
33  import java.util.List;
34  import java.util.Map;
35  
36  /**
37   * A PageGroup represents a page of a View.
38   *
39   * <p>
40   * PageGroups should only be used with a View component.  The contain the main content that will be seen by the
41   * user using the View.  Like all other groups, PageGroup can contain items, headers and footers.  Pages also
42   * have their own BreadcrumbItem.
43   * </p>
44   *
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   */
47  @BeanTags({@BeanTag(name = "page-bean", parent = "Uif-Page"),
48          @BeanTag(name = "disclosure-page-bean", parent = "Uif-Disclosure-Page"),
49          @BeanTag(name = "documentPage-bean", parent = "Uif-DocumentPage"),
50          @BeanTag(name = "inquiryPage-bean", parent = "Uif-InquiryPage"),
51          @BeanTag(name = "lookupPage-bean", parent = "Uif-LookupPage"),
52          @BeanTag(name = "maintenancePage-bean", parent = "Uif-MaintenancePage")})
53  public class PageGroup extends Group {
54      private static final long serialVersionUID = 7571981300587270274L;
55  
56      private boolean autoFocus = false;
57  
58      private PageBreadcrumbOptions breadcrumbOptions;
59      private BreadcrumbItem breadcrumbItem;
60      private boolean stickyFooter;
61  
62      /**
63       * Setup various breadcrumbOptions inherited from view if not explicitly set.
64       *
65       * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View,
66       *      Object)
67       */
68      @Override
69      public void performInitialization(View view, Object model) {
70          super.performInitialization(view, model);
71  
72          //check to see if one of the items is a page, if so throw an exception
73          for (Component item : this.getItems()) {
74              if (item != null && item instanceof PageGroup) {
75                  throw new RuntimeException("The page with id='"
76                          + this.getId()
77                          + "' contains a page with id='"
78                          + item.getId()
79                          + "'.  Nesting a page within a page is not allowed since only one "
80                          + "page's content can be shown on the View "
81                          + "at a time.  This may have been caused by possible misuse of the singlePageView flag (when "
82                          + "this flag is true, items set on the View become items of the single page.  Instead use "
83                          + "the page property on the View to set the page being used).");
84              }
85          }
86  
87          breadcrumbOptions.setupBreadcrumbs(view, model);
88      }
89  
90      /**
91       * Perform finalize here adds to its document ready script the
92       * setupValidator js function for setting up the validator for this view.  Also setup various breadcrumb related
93       * settings for the page.
94       *
95       * @see ContainerBase#performFinalize(org.kuali.rice.krad.uif.view.View,
96       *      Object, org.kuali.rice.krad.uif.component.Component)
97       */
98      @Override
99      public void performFinalize(View view, Object model, Component parent) {
100         super.performFinalize(view, model, parent);
101 
102         this.addDataAttribute(UifConstants.DataAttributes.TYPE, "Page");
103 
104         String prefixScript = "";
105         if (this.getOnDocumentReadyScript() != null) {
106             prefixScript = this.getOnDocumentReadyScript();
107         }
108 
109         if (view instanceof FormView && ((FormView) view).isValidateClientSide()) {
110             this.setOnDocumentReadyScript(prefixScript + "\nsetupPage(true);");
111         } else {
112             this.setOnDocumentReadyScript(prefixScript + "\nsetupPage(false);");
113         }
114 
115         breadcrumbOptions.finalizeBreadcrumbs(view, model, this, breadcrumbItem);
116     }
117 
118     /**
119      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
120      */
121     @Override
122     public List<Component> getComponentsForLifecycle() {
123         List<Component> components = new ArrayList<Component>();
124 
125         components.add(breadcrumbItem);
126 
127         if (breadcrumbOptions != null) {
128             if (breadcrumbOptions.getHomewardPathBreadcrumbs() != null) {
129                 components.addAll(breadcrumbOptions.getHomewardPathBreadcrumbs());
130             }
131 
132             if (breadcrumbOptions.getPreViewBreadcrumbs() != null) {
133                 components.addAll(breadcrumbOptions.getPreViewBreadcrumbs());
134             }
135 
136             if (breadcrumbOptions.getPrePageBreadcrumbs() != null) {
137                 components.addAll(breadcrumbOptions.getPrePageBreadcrumbs());
138             }
139 
140             if (breadcrumbOptions.getBreadcrumbOverrides() != null) {
141                 components.addAll(breadcrumbOptions.getBreadcrumbOverrides());
142             }
143         }
144 
145         components.addAll(super.getComponentsForLifecycle());
146 
147         return components;
148     }
149 
150     /**
151      * When this is true, the first field of the kualiForm will be focused by
152      * default, unless the parameter focusId is set on the form (by an
153      * actionField), then that field will be focused instead. When this setting
154      * if false, no field will be focused.
155      *
156      * @return the autoFocus
157      */
158     @BeanTagAttribute(name = "autoFocus")
159     public boolean isAutoFocus() {
160         return this.autoFocus;
161     }
162 
163     /**
164      * @param autoFocus the autoFocus to set
165      */
166     public void setAutoFocus(boolean autoFocus) {
167         this.autoFocus = autoFocus;
168     }
169 
170     /**
171      * The breadcrumbOptions specific to this page.
172      *
173      * <p>
174      * Important note: breadcrumbOptions for preViewBreadcrumbs, prePageBreadcrumbs, and
175      * breadcrumbOverrides are inherited from the View if not explicitly set from the PageGroup level's
176      * breadcrumbOptions
177      * (if they contain a value at the view level and the property is null at the page level - default behavior).
178      * Explicitly providing an empty list or setting these properties at the PageGroup level will
179      * override this inheritance.
180      * </p>
181      *
182      * @return the {@link BreadcrumbOptions}
183      */
184     @BeanTagAttribute(name = "breadcrumbOptions", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
185     public PageBreadcrumbOptions getBreadcrumbOptions() {
186         return breadcrumbOptions;
187     }
188 
189     /**
190      * Set the breadcrumbOptions
191      *
192      * @param breadcrumbOptions
193      */
194     public void setBreadcrumbOptions(PageBreadcrumbOptions breadcrumbOptions) {
195         this.breadcrumbOptions = breadcrumbOptions;
196     }
197 
198     /**
199      * The breadcrumbItem for this page.  This is the item that (generally) appears last in the breadcrumb list.
200      *
201      * <p>
202      * If a label is not explicitly defined, the label is retrieved from the headerText of the PageGroup's header.
203      * If this is also not defined, the breadcrumbItem is NOT rendered.  The url properties do not need to be provided
204      * for this breadcrumbItem because it is automatically determined based on the this PageGroup's pageId, viewId,
205      * and controllerMapping retrieved from the initial controller request.
206      * </p>
207      *
208      * @return the breadcrumbItem for this page
209      */
210     @BeanTagAttribute(name = "breadcrumbItem", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
211     public BreadcrumbItem getBreadcrumbItem() {
212         return breadcrumbItem;
213     }
214 
215     /**
216      * Set the breadcrumbItem for this PageGroup
217      *
218      * @param breadcrumbItem
219      */
220     public void setBreadcrumbItem(BreadcrumbItem breadcrumbItem) {
221         this.breadcrumbItem = breadcrumbItem;
222     }
223 
224     /**
225      * When true, this page's footer will become sticky (fixed) at the bottom of the window
226      *
227      * @return true if the page footer is sticky, false otherwise
228      */
229     @BeanTagAttribute(name = "stickyFooter")
230     public boolean isStickyFooter() {
231         return stickyFooter;
232     }
233 
234     /**
235      * Set to true to make this page's footer sticky
236      *
237      * @param stickyFooter
238      */
239     public void setStickyFooter(boolean stickyFooter) {
240         this.stickyFooter = stickyFooter;
241 
242         if (this.getFooter() != null) {
243             this.getFooter().addDataAttribute(UifConstants.DataAttributes.STICKY_FOOTER, Boolean.toString(
244                     stickyFooter));
245         }
246     }
247 
248     /**
249      * @see org.kuali.rice.krad.uif.component.ComponentBase#copy()
250      */
251     @Override
252     protected <T> void copyProperties(T component) {
253         super.copyProperties(component);
254 
255         PageGroup pageGroupCopy = (PageGroup) component;
256 
257         pageGroupCopy.setAutoFocus(this.isAutoFocus());
258         pageGroupCopy.setStickyFooter(this.isStickyFooter());
259 
260         if (breadcrumbOptions != null) {
261             pageGroupCopy.setBreadcrumbOptions((PageBreadcrumbOptions) this.getBreadcrumbOptions().copy());
262         }
263 
264         if (breadcrumbItem != null) {
265             pageGroupCopy.setBreadcrumbItem((BreadcrumbItem) this.getBreadcrumbItem().copy());
266         }
267     }
268 
269     /**
270      * @see org.kuali.rice.krad.uif.component.Component#completeValidation
271      */
272     @Override
273     public void completeValidation(ValidationTrace tracer) {
274         tracer.addBean(this);
275 
276         // Checks that no invalid items are present
277         for (int i = 0; i < getItems().size(); i++) {
278             if (getItems().get(i).getClass() == PageGroup.class || getItems().get(i).getClass()
279                     == NavigationGroup.class) {
280                 String currentValues[] = {"item(" + i + ").class =" + getItems().get(i).getClass()};
281                 tracer.createError("Items in PageGroup cannot be PageGroup or NaviagtionGroup", currentValues);
282             }
283         }
284 
285         super.completeValidation(tracer.getCopy());
286     }
287 }