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 }