001 /**
002 * Copyright 2005-2014 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 */
016 package org.kuali.rice.krad.uif.layout;
017
018 import java.util.ArrayList;
019 import java.util.List;
020
021 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
022 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
023 import org.kuali.rice.krad.uif.component.Component;
024 import org.kuali.rice.krad.uif.container.Container;
025 import org.kuali.rice.krad.uif.util.LifecycleElement;
026 import org.kuali.rice.krad.util.KRADUtils;
027
028 /**
029 * Css Grid Layout manager is a layout manager which creates div "rows" and "cells" to replicate a
030 * table look by using div elements for its items.
031 *
032 * <p>
033 * Items are added into rows based on their colSpan
034 * setting, while each row has a max size of 12 columns. By default, if colSpan is not set on an
035 * item, that item will take a full row.
036 * </p>
037 *
038 * @author Kuali Rice Team (rice.collab@kuali.org)
039 */
040 @BeanTag(name = "cssGridLayout-bean", parent = "Uif-CssGridLayout")
041 public class CssGridLayoutManager extends CssGridLayoutManagerBase {
042 private static final long serialVersionUID = 1830635073147703757L;
043
044 private int defaultItemColSpan;
045
046 /**
047 * CssGridLayoutManager's performFinalize method calculates and separates the items into rows
048 * based on their colSpan settings and the defaultItemColSpan setting
049 *
050 * {@inheritDoc}
051 */
052 @Override
053 public void performFinalize(Object model, LifecycleElement component) {
054 super.performFinalize(model, component);
055
056 Container container = (Container) component;
057 processNormalLayout(container);
058
059 }
060
061 /**
062 * Separates the container's items into the appropriate number of rows and div "cells" based on
063 * the defaultColSpan property settings and colSpan settings of the items
064 *
065 * @param container the container using this layout manager
066 */
067 private void processNormalLayout(Container container) {
068 int rowSpaceLeft = NUMBER_OF_COLUMNS;
069 int rowIndex = 0;
070 boolean isOdd = true;
071 List<Component> currentRow = new ArrayList<Component>();
072 for (Component item : container.getItems()) {
073 if (item == null) {
074 continue;
075 }
076 isOdd = rowIndex % 2 == 0;
077
078 // set colSpan to default setting (12 is the default)
079 int colSpan = this.defaultItemColSpan;
080
081 // if the item's set colSpan is greater than 1 set it to that number; 1 is the default colSpan for Component
082 if (item.getColSpan() > 1 && item.getColSpan() <= NUMBER_OF_COLUMNS) {
083 colSpan = item.getColSpan();
084 }
085
086 // determine "cell" div css
087 List<String> cellCssClasses = item.getWrapperCssClasses();
088 if (cellCssClasses == null) {
089 item.setWrapperCssClasses(new ArrayList<String>());
090 cellCssClasses = item.getWrapperCssClasses();
091 }
092 cellCssClasses.add(0, BOOTSTRAP_SPAN_PREFIX + colSpan);
093 cellCssClassAttributes.add(getCellStyleClassesAsString(cellCssClasses));
094
095 // calculate space left in row
096 rowSpaceLeft = rowSpaceLeft - colSpan;
097
098 if (rowSpaceLeft > 0) {
099 // 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 }