1 /** 2 * Copyright 2005-2012 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.kuali.rice.krad.datadictionary.parse.BeanTag; 19 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 20 import org.kuali.rice.krad.uif.container.Container; 21 import org.kuali.rice.krad.uif.container.Group; 22 import org.kuali.rice.krad.uif.view.View; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 27 /** 28 * Layout manager that organizes its components in a table based grid 29 * 30 * <p> 31 * Items are laid out from left to right (with each item taking up one column) 32 * until the configured number of columns is reached. If the item count is 33 * greater than the number of columns, a new row will be created to render the 34 * remaining items (and so on until all items are placed). Labels for the fields 35 * can be pulled out (default) and rendered as a separate column. The manager 36 * also supports the column span and row span options for the field items. If 37 * not specified the default is 1. 38 * </p> 39 * 40 * @author Kuali Rice Team (rice.collab@kuali.org) 41 */ 42 @BeanTag(name="gridLayoutManager") 43 public class GridLayoutManager extends LayoutManagerBase { 44 private static final long serialVersionUID = 1890011900375071128L; 45 46 private int numberOfColumns; 47 48 private boolean suppressLineWrapping; 49 private boolean applyAlternatingRowStyles; 50 private boolean applyDefaultCellWidths; 51 private boolean renderFirstRowHeader; 52 private boolean renderAlternatingHeaderColumns; 53 private boolean renderRowFirstCellHeader; 54 55 private List<String> rowCssClasses; 56 57 public GridLayoutManager() { 58 super(); 59 60 rowCssClasses = new ArrayList<String>(); 61 } 62 63 /** 64 * The following finalization is performed: 65 * 66 * <ul> 67 * <li>If suppressLineWrapping is true, sets the number of columns to the 68 * container's items list size</li> 69 * </ul> 70 * 71 * @see org.kuali.rice.krad.uif.layout.LayoutManagerBase#performFinalize(org.kuali.rice.krad.uif.view.View, 72 * java.lang.Object, org.kuali.rice.krad.uif.container.Container) 73 */ 74 @Override 75 public void performFinalize(View view, Object model, Container container) { 76 super.performFinalize(view, model, container); 77 78 if (suppressLineWrapping) { 79 numberOfColumns = container.getItems().size(); 80 } 81 } 82 83 /** 84 * @see LayoutManagerBase#getSupportedContainer() 85 */ 86 @Override 87 public Class<? extends Container> getSupportedContainer() { 88 return Group.class; 89 } 90 91 /** 92 * Indicates the number of columns that should make up one row of data 93 * 94 * <p> 95 * If the item count is greater than the number of columns, a new row will 96 * be created to render the remaining items (and so on until all items are 97 * placed). 98 * </p> 99 * 100 * <p> 101 * Note this does not include any generated columns by the layout manager, 102 * so the final column count could be greater (if label fields are 103 * separate). 104 * </p> 105 * 106 * @return 107 */ 108 @BeanTagAttribute(name="numberOfColumns") 109 public int getNumberOfColumns() { 110 return this.numberOfColumns; 111 } 112 113 /** 114 * Setter for the number of columns (each row) 115 * 116 * @param numberOfColumns 117 */ 118 public void setNumberOfColumns(int numberOfColumns) { 119 this.numberOfColumns = numberOfColumns; 120 } 121 122 /** 123 * Indicates whether the number of columns for the table data should match 124 * the number of fields given in the container's items list (so that each 125 * field takes up one column without wrapping), this overrides the configured 126 * numberOfColumns 127 * 128 * <p> 129 * If set to true during the initialize phase the number of columns will be 130 * set to the size of the container's field list, if false the configured 131 * number of columns is used 132 * </p> 133 * 134 * @return boolean true if the column count should match the container's 135 * field count, false to use the configured number of columns 136 */ 137 @BeanTagAttribute(name="suppressLineWrapping") 138 public boolean isSuppressLineWrapping() { 139 return this.suppressLineWrapping; 140 } 141 142 /** 143 * Setter for the suppressLineWrapping indicator 144 * 145 * @param suppressLineWrapping 146 */ 147 public void setSuppressLineWrapping(boolean suppressLineWrapping) { 148 this.suppressLineWrapping = suppressLineWrapping; 149 } 150 151 /** 152 * Indicates whether alternating row styles should be applied 153 * 154 * <p> 155 * Indicator to layout manager templates to apply alternating row styles. 156 * See the configured template for the actual style classes used 157 * </p> 158 * 159 * @return boolean true if alternating styles should be applied, false if 160 * all rows should have the same style 161 */ 162 @BeanTagAttribute(name="applyAlternatingRowStyles") 163 public boolean isApplyAlternatingRowStyles() { 164 return this.applyAlternatingRowStyles; 165 } 166 167 /** 168 * Setter for the alternating row styles indicator 169 * 170 * @param applyAlternatingRowStyles 171 */ 172 public void setApplyAlternatingRowStyles(boolean applyAlternatingRowStyles) { 173 this.applyAlternatingRowStyles = applyAlternatingRowStyles; 174 } 175 176 /** 177 * Indicates whether the manager should default the cell widths 178 * 179 * <p> 180 * If true, the manager will set the cell width by equally dividing by the 181 * number of columns 182 * </p> 183 * 184 * @return boolean true if default cell widths should be applied, false if 185 * no defaults should be applied 186 */ 187 @BeanTagAttribute(name="applyDefaultCellWidths") 188 public boolean isApplyDefaultCellWidths() { 189 return this.applyDefaultCellWidths; 190 } 191 192 /** 193 * Setter for the default cell width indicator 194 * 195 * @param applyDefaultCellWidths 196 */ 197 public void setApplyDefaultCellWidths(boolean applyDefaultCellWidths) { 198 this.applyDefaultCellWidths = applyDefaultCellWidths; 199 } 200 201 /** 202 * Indicates whether the first cell of each row should be rendered as a header cell (th) 203 * 204 * <p> 205 * When this flag is turned on, the first cell for each row will be rendered as a header cell. If 206 * {@link #isRenderAlternatingHeaderColumns()} is false, the remaining cells for the row will be rendered 207 * as data cells, else they will alternate between cell headers 208 * </p> 209 * 210 * @return boolean true if first cell of each row should be rendered as a header cell 211 */ 212 @BeanTagAttribute(name="renderRowFirstCellHeader") 213 public boolean isRenderRowFirstCellHeader() { 214 return renderRowFirstCellHeader; 215 } 216 217 /** 218 * Setter for render first row column as header indicator 219 * 220 * @param renderRowFirstCellHeader 221 */ 222 public void setRenderRowFirstCellHeader(boolean renderRowFirstCellHeader) { 223 this.renderRowFirstCellHeader = renderRowFirstCellHeader; 224 } 225 226 /** 227 * Indicates whether the first row of items rendered should all be rendered as table header (th) cells 228 * 229 * <p> 230 * Generally when using a grid layout all the cells will be tds or alternating th/td (with the label in the 231 * th cell). However in some cases it might be desired to display the labels in one row as table header cells (th) 232 * followed by a row with the corresponding fields in td cells. When this is enabled this type of layout is 233 * possible 234 * </p> 235 * 236 * @return boolean true if first row should be rendered as header cells 237 */ 238 @BeanTagAttribute(name="renderFirstRowHeader") 239 public boolean isRenderFirstRowHeader() { 240 return renderFirstRowHeader; 241 } 242 243 /** 244 * Setter for the first row as header indicator 245 * 246 * @param renderFirstRowHeader 247 */ 248 public void setRenderFirstRowHeader(boolean renderFirstRowHeader) { 249 this.renderFirstRowHeader = renderFirstRowHeader; 250 } 251 252 /** 253 * Indicates whether header columns (th for tables) should be rendered for 254 * every other item (alternating) 255 * 256 * <p> 257 * If true the first cell of each row will be rendered as an header, with 258 * every other cell in the row as a header 259 * </p> 260 * 261 * @return boolean true if alternating headers should be rendered, false if 262 * not 263 */ 264 @BeanTagAttribute(name="renderAlternatingHeaderColumns") 265 public boolean isRenderAlternatingHeaderColumns() { 266 return this.renderAlternatingHeaderColumns; 267 } 268 269 /** 270 * Setter for the render alternating header columns indicator 271 * 272 * @param renderAlternatingHeaderColumns 273 */ 274 public void setRenderAlternatingHeaderColumns(boolean renderAlternatingHeaderColumns) { 275 this.renderAlternatingHeaderColumns = renderAlternatingHeaderColumns; 276 } 277 278 /** 279 * The list of styles for each row 280 * 281 * <p> 282 * Each entry in the list gives the style for the row with the same index. This style will be added the the <tr> 283 * tag 284 * when the table rows are rendered in the grid.tag. This is used to store the styles for newly added lines and 285 * other special cases like the add item row. 286 * </p> 287 * 288 * @return List<String> list of styles for the rows 289 */ 290 @BeanTagAttribute(name="rowCssClasses",type= BeanTagAttribute.AttributeType.LISTVALUE) 291 public List<String> getRowCssClasses() { 292 return rowCssClasses; 293 } 294 295 /** 296 * Setter for the list that stores the css style names of each row 297 * 298 * @param rowCssClasses 299 */ 300 public void setRowCssClasses(List<String> rowCssClasses) { 301 this.rowCssClasses = rowCssClasses; 302 } 303 }