View Javadoc
1   /**
2    * Copyright 2005-2015 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.layout;
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.uif.CssConstants;
23  import org.kuali.rice.krad.uif.CssConstants.Padding;
24  import org.kuali.rice.krad.uif.UifConstants.Orientation;
25  import org.kuali.rice.krad.uif.component.Component;
26  import org.kuali.rice.krad.uif.container.Container;
27  import org.kuali.rice.krad.uif.element.Header;
28  import org.kuali.rice.krad.uif.element.Message;
29  import org.kuali.rice.krad.uif.element.MultiFileUploadCollection;
30  import org.kuali.rice.krad.uif.element.ProgressBar;
31  import org.kuali.rice.krad.uif.field.ProgressBarField;
32  import org.kuali.rice.krad.uif.util.LifecycleElement;
33  
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  /**
38   * Layout manager that organizes components in a single row (horizontal) or
39   * column (vertical)
40   *
41   * <p>
42   * Although a table based template could be used, setup is done to also support
43   * a CSS based template. The items in the <code>Container</code> instance are
44   * rendered sequentially wrapping each one with a span element. The padding
45   * property can be configured to space the elements as needed. To achieve a
46   * vertical orientation, the span style is set to block. Additional styling can
47   * be set for the items by using the itemSpanStyle property.
48   * </p>
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  @BeanTags({@BeanTag(name = "boxLayout", parent = "Uif-BoxLayoutBase"),
53          @BeanTag(name = "horizontalBoxLayout", parent = "Uif-HorizontalBoxLayout"),
54          @BeanTag(name = "verticalBoxLayout", parent = "Uif-VerticalBoxLayout")})
55  public class BoxLayoutManager extends LayoutManagerBase {
56      private static final long serialVersionUID = 4467342272983290044L;
57  
58      private Orientation orientation;
59      private String padding;
60  
61      private String itemStyle;
62      private List<String> itemStyleClasses;
63  
64      private boolean renderLayoutWrapper;
65  
66      public BoxLayoutManager() {
67          super();
68  
69          itemStyle = "";
70          orientation = Orientation.HORIZONTAL;
71          itemStyleClasses = new ArrayList<String>();
72      }
73  
74      /**
75       * Sets the item span style
76       *
77       * {@inheritDoc}
78       */
79      @Override
80      public void performFinalize(Object model, LifecycleElement container) {
81          super.performFinalize(model, container);
82  
83          if (StringUtils.isBlank(itemStyle)) {
84              itemStyle = "";
85          }
86  
87          if (StringUtils.isNotEmpty(padding)) {
88              if (orientation.equals(Orientation.VERTICAL)) {
89                  // set item to block which will cause a line break and margin
90                  // bottom for padding
91                  itemStyle += CssConstants.getCssStyle(Padding.PADDING_BOTTOM, padding);
92              } else {
93                  // set margin right for padding
94                  itemStyle += CssConstants.getCssStyle(Padding.PADDING_RIGHT, padding);
95              }
96          }
97  
98          for (Component c : ((Container) container).getItems()) {
99              if (c != null) {
100                 if (orientation.equals(Orientation.HORIZONTAL)) {
101                     c.addStyleClass("uif-boxLayoutHorizontalItem");
102 
103                     ((Component) container).addStyleClass("clearfix");
104 
105                     for (String styleClass : this.getItemStyleClasses()) {
106                         c.addStyleClass(styleClass);
107                     }
108 
109                 } else {
110                     c.addStyleClass("uif-boxLayoutVerticalItem");
111 
112                     if (!(c instanceof Header
113                             || c instanceof Container
114                             || c instanceof Message
115                             || c instanceof ProgressBar
116                             || c instanceof ProgressBarField
117                             || c instanceof MultiFileUploadCollection)) {
118                         c.addStyleClass("pull-left");
119                     }
120 
121                     for (String styleClass : this.getItemStyleClasses()) {
122                         c.addStyleClass(styleClass);
123                     }
124 
125                     c.addStyleClass("clearfix");
126                 }
127 
128                 if (c.getStyle() != null && !c.getStyle().endsWith(";")) {
129                     c.appendToStyle(";" + this.getItemStyle());
130                 } else {
131                     c.appendToStyle(this.getItemStyle());
132                 }
133             }
134         }
135     }
136 
137     /**
138      * Indicates whether the components should be rendered in a horizontal or
139      * vertical column
140      *
141      * @return orientation configured for layout
142      */
143     @BeanTagAttribute
144     public Orientation getOrientation() {
145         return this.orientation;
146     }
147 
148     /**
149      * Setter for the orientation for layout
150      *
151      * @param orientation
152      */
153     public void setOrientation(Orientation orientation) {
154         this.orientation = orientation;
155     }
156 
157     /**
158      * Amount of separation between each item
159      *
160      * <p>
161      * For horizontal orientation, this will be the right padding for each item.
162      * For vertical, it will be the bottom padding for each item. The value can
163      * be a fixed length (like px) or percentage
164      * </p>
165      *
166      * @return String
167      */
168     @BeanTagAttribute
169     public String getPadding() {
170         return this.padding;
171     }
172 
173     /**
174      * Setter for the item padding
175      *
176      * @param padding
177      */
178     public void setPadding(String padding) {
179         this.padding = padding;
180     }
181 
182     /**
183      * Used by the render to set the style on the span element that wraps the
184      * item. By using a wrapping span the items can be aligned based on the
185      * orientation and given the correct padding
186      *
187      * @return css style string
188      */
189     @BeanTagAttribute
190     public String getItemStyle() {
191         return this.itemStyle;
192     }
193 
194     /**
195      * Setter for the span style
196      *
197      * @param itemStyle
198      */
199     public void setItemStyle(String itemStyle) {
200         this.itemStyle = itemStyle;
201     }
202 
203     /**
204      * List of style classes that should be applied to each span that wraps the item in the layout
205      *
206      * @return List<String>
207      */
208     @BeanTagAttribute
209     public List<String> getItemStyleClasses() {
210         return itemStyleClasses;
211     }
212 
213     /**
214      * Setter for the list of style classes that should apply to each item span
215      *
216      * @param itemStyleClasses
217      */
218     public void setItemStyleClasses(List<String> itemStyleClasses) {
219         this.itemStyleClasses = itemStyleClasses;
220     }
221 
222     /**
223      * Builds the HTML class attribute string by combining the item styleClasses list
224      * with a space delimiter
225      *
226      * @return class attribute string
227      */
228     public String getItemStyleClassesAsString() {
229         if (itemStyleClasses != null) {
230             return StringUtils.join(itemStyleClasses, " ");
231         }
232 
233         return "";
234     }
235 
236     public boolean isRenderLayoutWrapper() {
237         return renderLayoutWrapper;
238     }
239 
240     public void setRenderLayoutWrapper(boolean renderLayoutWrapper) {
241         this.renderLayoutWrapper = renderLayoutWrapper;
242     }
243 }