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.layout;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
22  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
23  import org.kuali.rice.krad.uif.component.Component;
24  import org.kuali.rice.krad.uif.container.Container;
25  import org.kuali.rice.krad.uif.util.LifecycleElement;
26  import org.kuali.rice.krad.util.KRADUtils;
27  
28  /**
29   * Css Grid Layout manager is a layout manager which creates div "rows" and "cells" to replicate a
30   * table look by using div elements for its items.
31   *
32   * <p>
33   * Items are added into rows based on their colSpan
34   * setting, while each row has a max size of 12 columns. By default, if colSpan is not set on an
35   * item, that item will take a full row.
36   * </p>
37   *
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   */
40  @BeanTag(name = "cssGridLayout-bean", parent = "Uif-CssGridLayout")
41  public class CssGridLayoutManager extends CssGridLayoutManagerBase {
42      private static final long serialVersionUID = 1830635073147703757L;
43  
44      private int defaultItemColSpan;
45  
46      /**
47       * CssGridLayoutManager's performFinalize method calculates and separates the items into rows
48       * based on their colSpan settings and the defaultItemColSpan setting
49       *
50       * {@inheritDoc}
51       */
52      @Override
53      public void performFinalize(Object model, LifecycleElement component) {
54          super.performFinalize(model, component);
55  
56          Container container = (Container) component;
57          processNormalLayout(container);
58  
59      }
60  
61      /**
62       * Separates the container's items into the appropriate number of rows and div "cells" based on
63       * the defaultColSpan property settings and colSpan settings of the items
64       *
65       * @param container the container using this layout manager
66       */
67      private void processNormalLayout(Container container) {
68          int rowSpaceLeft = NUMBER_OF_COLUMNS;
69          int rowIndex = 0;
70          boolean isOdd = true;
71          List<Component> currentRow = new ArrayList<Component>();
72          for (Component item : container.getItems()) {
73              if (item == null) {
74                  continue;
75              }
76              isOdd = rowIndex % 2 == 0;
77  
78              // set colSpan to default setting (12 is the default)
79              int colSpan = this.defaultItemColSpan;
80  
81              // if the item's set colSpan is greater than 1 set it to that number; 1 is the default colSpan for Component
82              if (item.getColSpan() > 1 && item.getColSpan() <= NUMBER_OF_COLUMNS) {
83                  colSpan = item.getColSpan();
84              }
85  
86              // determine "cell" div css
87              List<String> cellCssClasses = item.getWrapperCssClasses();
88              if (cellCssClasses == null) {
89                  item.setWrapperCssClasses(new ArrayList<String>());
90                  cellCssClasses = item.getWrapperCssClasses();
91              }
92              cellCssClasses.add(0, BOOTSTRAP_SPAN_PREFIX + colSpan);
93              cellCssClassAttributes.add(getCellStyleClassesAsString(cellCssClasses));
94  
95              // calculate space left in row
96              rowSpaceLeft = rowSpaceLeft - colSpan;
97  
98              if (rowSpaceLeft > 0) {
99                  // space is left, just add item to row
100                 currentRow.add(item);
101             } else if (rowSpaceLeft < 0) {
102                 // went over, add item to next new row
103                 rows.add(new ArrayList<Component>(currentRow));
104                 currentRow = new ArrayList<Component>();
105                 currentRow.add(item);
106 
107                 // determine "row" div css
108                 String rowCss = rowLayoutCssClass + " " + KRADUtils.generateRowCssClassString(conditionalRowCssClasses,
109                         rowIndex, isOdd, null, null);
110                 rowCssClassAttributes.add(rowCss);
111 
112                 rowIndex++;
113                 rowSpaceLeft = NUMBER_OF_COLUMNS - colSpan;
114             } else if (rowSpaceLeft == 0) {
115                 // last item in row, create new row
116                 currentRow.add(item);
117                 rows.add(new ArrayList<Component>(currentRow));
118                 currentRow = new ArrayList<Component>();
119 
120                 // determine "row" div css
121                 String rowCss = rowLayoutCssClass + " " + KRADUtils.generateRowCssClassString(conditionalRowCssClasses,
122                         rowIndex, isOdd, null, null);
123                 rowCssClassAttributes.add(rowCss);
124 
125                 rowIndex++;
126                 rowSpaceLeft = NUMBER_OF_COLUMNS;
127             }
128         }
129 
130         isOdd = rowIndex % 2 == 0;
131         // add the last row if it wasn't full (but has items)
132         if (!currentRow.isEmpty()) {
133             // determine "row" div css
134             String rowCss = rowLayoutCssClass + " " + KRADUtils.generateRowCssClassString(conditionalRowCssClasses,
135                     rowIndex, isOdd, null, null);
136             rowCssClassAttributes.add(rowCss);
137 
138             rows.add(currentRow);
139         }
140     }
141 
142     /**
143      * The default cell colSpan to use for this layout (max setting, and the bean default, is 12)
144      *
145      * @return int representing the default colSpan for cells in this layout
146      */
147     @BeanTagAttribute(name = "defaultItemColSpan")
148     public int getDefaultItemColSpan() {
149         return defaultItemColSpan;
150     }
151 
152     /**
153      * Set the default colSpan for this layout's items
154      *
155      * @param defaultItemColSpan
156      */
157     public void setDefaultItemColSpan(int defaultItemColSpan) {
158         this.defaultItemColSpan = defaultItemColSpan;
159     }
160 
161 }