View Javadoc

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