Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TableLayoutManager |
|
| 2.1944444444444446;2.194 |
1 | /* | |
2 | * Copyright 2007 The Kuali Foundation | |
3 | * | |
4 | * Licensed under the Educational Community License, Version 1.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/ecl1.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.kns.uif.layout; | |
17 | ||
18 | import java.util.ArrayList; | |
19 | import java.util.Date; | |
20 | import java.util.List; | |
21 | ||
22 | import org.apache.commons.lang.ClassUtils; | |
23 | import org.apache.commons.lang.StringUtils; | |
24 | import org.kuali.rice.kns.uif.UifConstants; | |
25 | import org.kuali.rice.kns.uif.container.CollectionGroup; | |
26 | import org.kuali.rice.kns.uif.container.Container; | |
27 | import org.kuali.rice.kns.uif.container.View; | |
28 | import org.kuali.rice.kns.uif.core.Component; | |
29 | import org.kuali.rice.kns.uif.field.ActionField; | |
30 | import org.kuali.rice.kns.uif.field.AttributeField; | |
31 | import org.kuali.rice.kns.uif.field.Field; | |
32 | import org.kuali.rice.kns.uif.field.GroupField; | |
33 | import org.kuali.rice.kns.uif.field.LabelField; | |
34 | import org.kuali.rice.kns.uif.util.ComponentUtils; | |
35 | import org.kuali.rice.kns.uif.util.ObjectPropertyUtils; | |
36 | import org.kuali.rice.kns.uif.widget.TableTools; | |
37 | import org.kuali.rice.kns.web.spring.form.InquiryForm; | |
38 | import org.kuali.rice.kns.web.spring.form.LookupForm; | |
39 | ||
40 | /** | |
41 | * Layout manager that works with <code>CollectionGroup</code> components and | |
42 | * renders the collection as a Table | |
43 | * | |
44 | * <p> | |
45 | * Based on the fields defined, the <code>TableLayoutManager</code> will | |
46 | * dynamically create instances of the fields for each collection row. In | |
47 | * addition, the manager can create standard fields like the action and sequence | |
48 | * fields for each row. The manager supports options inherited from the | |
49 | * <code>GridLayoutManager</code> such as rowSpan, colSpan, and cell width | |
50 | * settings. | |
51 | * </p> | |
52 | * | |
53 | * @author Kuali Rice Team (rice.collab@kuali.org) | |
54 | */ | |
55 | public class TableLayoutManager extends GridLayoutManager implements CollectionLayoutManager { | |
56 | private static final long serialVersionUID = 3622267585541524208L; | |
57 | ||
58 | private boolean useShortLabels; | |
59 | private boolean repeatHeader; | |
60 | private LabelField headerFieldPrototype; | |
61 | ||
62 | private boolean renderSequenceField; | |
63 | private String conditionalRenderSequenceField; | |
64 | private AttributeField sequenceFieldPrototype; | |
65 | ||
66 | private GroupField actionFieldPrototype; | |
67 | ||
68 | private GroupField subCollectionGroupFieldPrototype; | |
69 | ||
70 | // internal counter for the data columns (not including sequence, action) | |
71 | private int numberOfDataColumns; | |
72 | ||
73 | private List<LabelField> headerFields; | |
74 | private List<Field> dataFields; | |
75 | ||
76 | private TableTools tableTools; | |
77 | 0 | private boolean headerAdded = false; |
78 | ||
79 | 0 | public TableLayoutManager() { |
80 | 0 | useShortLabels = true; |
81 | 0 | repeatHeader = false; |
82 | 0 | renderSequenceField = true; |
83 | ||
84 | 0 | headerFields = new ArrayList<LabelField>(); |
85 | 0 | dataFields = new ArrayList<Field>(); |
86 | 0 | } |
87 | ||
88 | /** | |
89 | * The following actions are performed: | |
90 | * | |
91 | * <ul> | |
92 | * <li>Initializes the prototypes</li> | |
93 | * </ul> | |
94 | * | |
95 | * @see org.kuali.rice.kns.uif.layout.BoxLayoutManager#performInitialization(org.kuali.rice.kns.uif.container.View, | |
96 | * org.kuali.rice.kns.uif.container.Container) | |
97 | */ | |
98 | @Override | |
99 | public void performInitialization(View view, Container container) { | |
100 | 0 | super.performInitialization(view, container); |
101 | ||
102 | 0 | view.getViewHelperService().performComponentInitialization(view, headerFieldPrototype); |
103 | 0 | view.getViewHelperService().performComponentInitialization(view, sequenceFieldPrototype); |
104 | 0 | view.getViewHelperService().performComponentInitialization(view, actionFieldPrototype); |
105 | 0 | view.getViewHelperService().performComponentInitialization(view, subCollectionGroupFieldPrototype); |
106 | 0 | } |
107 | ||
108 | /** | |
109 | * The following actions are performed: | |
110 | * | |
111 | * <ul> | |
112 | * <li>Sets internal count of columns to configured number</li> | |
113 | * </ul> | |
114 | * | |
115 | * @see org.kuali.rice.kns.uif.layout.LayoutManagerBase#performApplyModel(org.kuali.rice.kns.uif.container.View, | |
116 | * java.lang.Object, org.kuali.rice.kns.uif.container.Container) | |
117 | */ | |
118 | @Override | |
119 | public void performApplyModel(View view, Object model, Container container) { | |
120 | 0 | super.performApplyModel(view, model, container); |
121 | ||
122 | 0 | setNumberOfDataColumns(getNumberOfColumns()); |
123 | 0 | } |
124 | ||
125 | /** | |
126 | * Sets up the final column count for rendering based on whether the | |
127 | * sequence and action fields have been generated | |
128 | * | |
129 | * @see org.kuali.rice.kns.uif.layout.LayoutManagerBase#performFinalize(org.kuali.rice.kns.uif.container.View, | |
130 | * java.lang.Object, org.kuali.rice.kns.uif.container.Container) | |
131 | */ | |
132 | @Override | |
133 | public void performFinalize(View view, Object model, Container container) { | |
134 | 0 | super.performFinalize(view, model, container); |
135 | ||
136 | 0 | CollectionGroup collectionGroup = (CollectionGroup) container; |
137 | ||
138 | 0 | int totalColumns = getNumberOfDataColumns(); |
139 | 0 | if (renderSequenceField) { |
140 | 0 | totalColumns++; |
141 | } | |
142 | ||
143 | 0 | if (collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly()) { |
144 | 0 | totalColumns++; |
145 | } | |
146 | ||
147 | 0 | setNumberOfColumns(totalColumns); |
148 | ||
149 | 0 | if (tableTools != null) { |
150 | ||
151 | /** | |
152 | * If subcollection exists, dont allow the table sortable | |
153 | */ | |
154 | 0 | if (!collectionGroup.getSubCollections().isEmpty()){ |
155 | 0 | tableTools.setDisableTableSort(true); |
156 | } | |
157 | ||
158 | 0 | if (!tableTools.isDisableTableSort()){ |
159 | /** | |
160 | * If rendering add line, skip that row from col sorting | |
161 | */ | |
162 | 0 | if (collectionGroup.isRenderAddLine() && !collectionGroup.isReadOnly()) { |
163 | 0 | tableTools.getComponentOptions().put(UifConstants.TableToolsKeys.SORT_SKIP_ROWS, "[" + UifConstants.TableToolsValues.ADD_ROW_DEFAULT_INDEX + "]"); |
164 | } | |
165 | ||
166 | 0 | if (!collectionGroup.isReadOnly()) { |
167 | 0 | buildTableToolsColumnOptions(collectionGroup); |
168 | } | |
169 | } | |
170 | ||
171 | } | |
172 | 0 | } |
173 | ||
174 | /** | |
175 | * Assembles the field instances for the collection line. The given sequence | |
176 | * field prototype is copied for the line sequence field. Likewise a copy of | |
177 | * the actionFieldPrototype is made and the given actions are set as the | |
178 | * items for the action field. Finally the generated items are assembled | |
179 | * together into the dataFields list with the given lineFields. | |
180 | * | |
181 | * @see org.kuali.rice.kns.uif.layout.CollectionLayoutManager#buildLine(org.kuali.rice.kns.uif.container.View, | |
182 | * java.lang.Object, org.kuali.rice.kns.uif.container.CollectionGroup, | |
183 | * java.util.List, java.util.List, java.lang.String, java.util.List, | |
184 | * java.lang.String, java.lang.Object, int) | |
185 | */ | |
186 | public void buildLine(View view, Object model, CollectionGroup collectionGroup, List<Field> lineFields, | |
187 | List<GroupField> subCollectionFields, String bindingPath, List<ActionField> actions, String idSuffix, | |
188 | Object currentLine, int lineIndex) { | |
189 | 0 | boolean isAddLine = lineIndex == -1; |
190 | ||
191 | // if add line build table header first | |
192 | // TODO: implement repeat header | |
193 | 0 | if (!headerAdded) { |
194 | 0 | headerFields = new ArrayList<LabelField>(); |
195 | 0 | dataFields = new ArrayList<Field>(); |
196 | ||
197 | 0 | buildTableHeaderRows(collectionGroup); |
198 | 0 | ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.LINE, currentLine); |
199 | 0 | ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.INDEX, new Integer( |
200 | lineIndex)); | |
201 | 0 | headerAdded = true; |
202 | } | |
203 | ||
204 | // set label field rendered to true on line fields | |
205 | 0 | for (Field field : lineFields) { |
206 | 0 | field.setLabelFieldRendered(true); |
207 | ||
208 | // don't display summary message | |
209 | // TODO: remove once we have modifier | |
210 | 0 | ComponentUtils.setComponentPropertyDeep(field, "summaryMessageField.render", new Boolean(false)); |
211 | } | |
212 | ||
213 | 0 | int rowCount = calculateNumberOfRows(collectionGroup.getItems()); |
214 | 0 | int rowSpan = rowCount + subCollectionFields.size(); |
215 | ||
216 | // sequence field is always first and should span all rows for the line | |
217 | 0 | if (renderSequenceField) { |
218 | 0 | Field sequenceField = null; |
219 | 0 | if (!isAddLine) { |
220 | 0 | sequenceField = ComponentUtils.copy(sequenceFieldPrototype); |
221 | } | |
222 | else { | |
223 | 0 | sequenceField = ComponentUtils.copy(collectionGroup.getAddLineLabelField()); |
224 | } | |
225 | 0 | sequenceField.setRowSpan(rowSpan); |
226 | ||
227 | 0 | if (sequenceField instanceof AttributeField) { |
228 | 0 | ((AttributeField) sequenceField).getBindingInfo().setBindByNamePrefix(bindingPath); |
229 | 0 | view.getViewIndex().addAttributeField((AttributeField) sequenceField); |
230 | } | |
231 | ||
232 | 0 | ComponentUtils.updateContextForLine(sequenceField, currentLine, lineIndex); |
233 | ||
234 | 0 | dataFields.add(sequenceField); |
235 | } | |
236 | ||
237 | // now add the fields in the correct position | |
238 | 0 | int cellPosition = 0; |
239 | 0 | for (Field lineField : lineFields) { |
240 | 0 | dataFields.add(lineField); |
241 | ||
242 | 0 | cellPosition += lineField.getColSpan(); |
243 | ||
244 | // action field should be in last column | |
245 | 0 | if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions() |
246 | && !collectionGroup.isReadOnly()) { | |
247 | 0 | GroupField lineActionsField = ComponentUtils.copy(actionFieldPrototype); |
248 | ||
249 | 0 | ComponentUtils.updateContextForLine(lineActionsField, currentLine, lineIndex); |
250 | 0 | lineActionsField.setRowSpan(rowSpan); |
251 | 0 | lineActionsField.setItems(actions); |
252 | ||
253 | 0 | dataFields.add(lineActionsField); |
254 | 0 | } |
255 | } | |
256 | ||
257 | // update colspan on sub-collection fields | |
258 | 0 | for (GroupField subCollectionField : subCollectionFields) { |
259 | 0 | subCollectionField.setColSpan(numberOfDataColumns); |
260 | } | |
261 | ||
262 | // add sub-collection fields to end of data fields | |
263 | 0 | dataFields.addAll(subCollectionFields); |
264 | 0 | } |
265 | ||
266 | /** | |
267 | * Create the <code>LabelField</code> instances that will be used to render | |
268 | * the table header | |
269 | * | |
270 | * <p> | |
271 | * For each column, a copy of headerFieldPrototype is made that determines | |
272 | * the label configuration. The actual label text comes from the field for | |
273 | * which the header applies to. The first column is always the sequence (if | |
274 | * enabled) and the last column contains the actions. Both the sequence and | |
275 | * action header fields will span all rows for the header. | |
276 | * </p> | |
277 | * | |
278 | * <p> | |
279 | * The headerFields list will contain the final list of header fields built | |
280 | * </p> | |
281 | * | |
282 | * @param collectionGroup | |
283 | * - CollectionGroup container the table applies to | |
284 | */ | |
285 | protected void buildTableHeaderRows(CollectionGroup collectionGroup) { | |
286 | // row count needed to determine the row span for the sequence and | |
287 | // action fields, since they should span all rows for the line | |
288 | 0 | int rowCount = calculateNumberOfRows(collectionGroup.getItems()); |
289 | ||
290 | // first column is sequence label | |
291 | 0 | if (renderSequenceField) { |
292 | 0 | sequenceFieldPrototype.setLabelFieldRendered(true); |
293 | 0 | sequenceFieldPrototype.setRowSpan(rowCount); |
294 | 0 | addHeaderField(sequenceFieldPrototype, 1); |
295 | } | |
296 | ||
297 | // pull out label fields from the container's items | |
298 | 0 | int cellPosition = 0; |
299 | 0 | for (Component component : collectionGroup.getItems()) { |
300 | 0 | Field field = (Field) component; |
301 | ||
302 | 0 | cellPosition += field.getColSpan(); |
303 | 0 | addHeaderField(field, cellPosition); |
304 | ||
305 | // add action header as last column in row | |
306 | 0 | if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions() |
307 | && !collectionGroup.isReadOnly()) { | |
308 | 0 | actionFieldPrototype.setLabelFieldRendered(true); |
309 | 0 | actionFieldPrototype.setRowSpan(rowCount); |
310 | 0 | addHeaderField(actionFieldPrototype, cellPosition); |
311 | } | |
312 | 0 | } |
313 | 0 | } |
314 | ||
315 | /** | |
316 | * Creates a new instance of the header field prototype and then sets the | |
317 | * label to the short (if useShortLabels is set to true) or long label of | |
318 | * the given component. After created the header field is added to the list | |
319 | * making up the table header | |
320 | * | |
321 | * @param field | |
322 | * - field instance the header field is being created for | |
323 | * @param column | |
324 | * - column number for the header, used for setting the id | |
325 | */ | |
326 | protected void addHeaderField(Field field, int column) { | |
327 | 0 | LabelField headerField = ComponentUtils.copy(headerFieldPrototype); |
328 | 0 | if (useShortLabels) { |
329 | 0 | headerField.setLabelText(field.getLabel()); |
330 | } | |
331 | else { | |
332 | 0 | headerField.setLabelText(field.getLabel()); |
333 | } | |
334 | ||
335 | 0 | headerField.setRowSpan(field.getRowSpan()); |
336 | 0 | headerField.setColSpan(field.getColSpan()); |
337 | ||
338 | 0 | if ((field.getRequired() != null) && field.getRequired().booleanValue()) { |
339 | 0 | headerField.getRequiredMessageField().setRender(true); |
340 | } | |
341 | else { | |
342 | 0 | headerField.getRequiredMessageField().setRender(false); |
343 | } | |
344 | ||
345 | 0 | headerFields.add(headerField); |
346 | 0 | } |
347 | ||
348 | /** | |
349 | * Calculates how many rows will be needed per collection line to display | |
350 | * the list of fields. Assumption is made that the total number of cells the | |
351 | * fields take up is evenly divisible by the configured number of columns | |
352 | * | |
353 | * @param items | |
354 | * - list of items that make up one collection line | |
355 | * @return int number of rows | |
356 | */ | |
357 | protected int calculateNumberOfRows(List<? extends Field> items) { | |
358 | 0 | int rowCount = 0; |
359 | ||
360 | 0 | int cellCount = 0; |
361 | 0 | for (Field field : items) { |
362 | 0 | cellCount += field.getColSpan() + field.getRowSpan() - 1; |
363 | } | |
364 | ||
365 | 0 | if (cellCount != 0) { |
366 | 0 | rowCount = cellCount / getNumberOfDataColumns(); |
367 | } | |
368 | ||
369 | 0 | return rowCount; |
370 | } | |
371 | ||
372 | protected void buildTableToolsColumnOptions(CollectionGroup collectionGroup) { | |
373 | ||
374 | 0 | StringBuffer tableToolsColumnOptions = new StringBuffer("["); |
375 | ||
376 | 0 | if (isRenderSequenceField()) { |
377 | 0 | tableToolsColumnOptions.append(" null ,"); |
378 | } | |
379 | ||
380 | 0 | for (Component component : collectionGroup.getItems()) { |
381 | /** | |
382 | * For GroupField, get the first field from that group | |
383 | */ | |
384 | 0 | if (component instanceof GroupField){ |
385 | 0 | component = ((GroupField)component).getItems().get(0); |
386 | } | |
387 | 0 | Class dataTypeClass = ObjectPropertyUtils.getPropertyType(collectionGroup.getCollectionObjectClass(), ((AttributeField)component).getPropertyName()); |
388 | 0 | String colOptions = constructTableColumnOptions(true, dataTypeClass); |
389 | 0 | tableToolsColumnOptions.append(colOptions + " , "); |
390 | ||
391 | 0 | } |
392 | ||
393 | 0 | if (collectionGroup.isRenderLineActions()) { |
394 | 0 | String colOptions = constructTableColumnOptions(false, null); |
395 | 0 | tableToolsColumnOptions.append(colOptions); |
396 | 0 | }else{ |
397 | 0 | tableToolsColumnOptions = new StringBuffer(StringUtils.removeEnd(tableToolsColumnOptions.toString(), ", ")); |
398 | } | |
399 | ||
400 | 0 | tableToolsColumnOptions.append("]"); |
401 | ||
402 | 0 | tableTools.getComponentOptions().put(UifConstants.TableToolsKeys.AO_COLUMNS, tableToolsColumnOptions.toString()); |
403 | 0 | } |
404 | ||
405 | /** | |
406 | * | |
407 | * This method constructs the sort data type for each datatable columns. | |
408 | * | |
409 | */ | |
410 | public String constructTableColumnOptions(boolean isSortable, Class dataTypeClass){ | |
411 | ||
412 | 0 | String colOptions = "null"; |
413 | ||
414 | 0 | if (!isSortable || dataTypeClass == null){ |
415 | 0 | colOptions = "{ \"" + UifConstants.TableToolsKeys.SORTABLE + "\" : false } "; |
416 | }else{ | |
417 | 0 | if (ClassUtils.isAssignable(dataTypeClass, String.class)){ |
418 | 0 | colOptions = "{ \"" + UifConstants.TableToolsKeys.SORT_DATA_TYPE + "\" : \"" + UifConstants.TableToolsValues.DOM_TEXT + "\" } "; |
419 | 0 | }else if (ClassUtils.isAssignable(dataTypeClass, Date.class)){ |
420 | 0 | colOptions = "{ \"" + UifConstants.TableToolsKeys.SORT_DATA_TYPE + "\" : \"" + UifConstants.TableToolsValues.DOM_TEXT + "\" , \"" + UifConstants.TableToolsKeys.SORT_TYPE + "\" : \"" + UifConstants.TableToolsValues.DATE + "\" } "; |
421 | 0 | }else if (ClassUtils.isAssignable(dataTypeClass, Number.class)){ |
422 | 0 | colOptions = "{ \"" + UifConstants.TableToolsKeys.SORT_DATA_TYPE + "\" : \"" + UifConstants.TableToolsValues.DOM_TEXT + "\" , \"" + UifConstants.TableToolsKeys.SORT_TYPE + "\" : \"" + UifConstants.TableToolsValues.NUMERIC + "\" } "; |
423 | } | |
424 | } | |
425 | ||
426 | 0 | return colOptions; |
427 | } | |
428 | ||
429 | /** | |
430 | * @see org.kuali.rice.kns.uif.layout.ContainerAware#getSupportedContainer() | |
431 | */ | |
432 | @Override | |
433 | public Class<? extends Container> getSupportedContainer() { | |
434 | 0 | return CollectionGroup.class; |
435 | } | |
436 | ||
437 | /** | |
438 | * @see org.kuali.rice.kns.uif.layout.LayoutManagerBase#getNestedComponents() | |
439 | */ | |
440 | @Override | |
441 | public List<Component> getNestedComponents() { | |
442 | 0 | List<Component> components = super.getNestedComponents(); |
443 | ||
444 | 0 | components.add(tableTools); |
445 | 0 | components.addAll(headerFields); |
446 | 0 | components.addAll(dataFields); |
447 | ||
448 | 0 | return components; |
449 | } | |
450 | ||
451 | /** | |
452 | * Indicates whether the short label for the collection field should be used | |
453 | * as the table header or the regular label | |
454 | * | |
455 | * @return boolean true if short label should be used, false if long label | |
456 | * should be used | |
457 | */ | |
458 | public boolean isUseShortLabels() { | |
459 | 0 | return this.useShortLabels; |
460 | } | |
461 | ||
462 | /** | |
463 | * Setter for the use short label indicator | |
464 | * | |
465 | * @param useShortLabels | |
466 | */ | |
467 | public void setUseShortLabels(boolean useShortLabels) { | |
468 | 0 | this.useShortLabels = useShortLabels; |
469 | 0 | } |
470 | ||
471 | /** | |
472 | * Indicates whether the header should be repeated before each collection | |
473 | * row. If false the header is only rendered at the beginning of the table | |
474 | * | |
475 | * @return boolean true if header should be repeated, false if it should | |
476 | * only be rendered once | |
477 | */ | |
478 | public boolean isRepeatHeader() { | |
479 | 0 | return this.repeatHeader; |
480 | } | |
481 | ||
482 | /** | |
483 | * Setter for the repeat header indicator | |
484 | * | |
485 | * @param repeatHeader | |
486 | */ | |
487 | public void setRepeatHeader(boolean repeatHeader) { | |
488 | 0 | this.repeatHeader = repeatHeader; |
489 | 0 | } |
490 | ||
491 | /** | |
492 | * <code>LabelField</code> instance to use as a prototype for creating the | |
493 | * tables header fields. For each header field the prototype will be copied | |
494 | * and adjusted as necessary | |
495 | * | |
496 | * @return LabelField instance to serve as prototype | |
497 | */ | |
498 | public LabelField getHeaderFieldPrototype() { | |
499 | 0 | return this.headerFieldPrototype; |
500 | } | |
501 | ||
502 | /** | |
503 | * Setter for the header field prototype | |
504 | * | |
505 | * @param headerFieldPrototype | |
506 | */ | |
507 | public void setHeaderFieldPrototype(LabelField headerFieldPrototype) { | |
508 | 0 | this.headerFieldPrototype = headerFieldPrototype; |
509 | 0 | } |
510 | ||
511 | /** | |
512 | * List of <code>LabelField</code> instances that should be rendered to make | |
513 | * up the tables header | |
514 | * | |
515 | * @return List of label field instances | |
516 | */ | |
517 | public List<LabelField> getHeaderFields() { | |
518 | 0 | return this.headerFields; |
519 | } | |
520 | ||
521 | /** | |
522 | * Indicates whether the sequence field should be rendered for the | |
523 | * collection | |
524 | * | |
525 | * @return boolean true if sequence field should be rendered, false if not | |
526 | */ | |
527 | public boolean isRenderSequenceField() { | |
528 | 0 | return this.renderSequenceField; |
529 | } | |
530 | ||
531 | /** | |
532 | * Setter for the render sequence field indicator | |
533 | * | |
534 | * @param renderSequenceField | |
535 | */ | |
536 | public void setRenderSequenceField(boolean renderSequenceField) { | |
537 | 0 | this.renderSequenceField = renderSequenceField; |
538 | 0 | } |
539 | ||
540 | /** | |
541 | * Expression language string for conditionally setting the render sequence | |
542 | * field property | |
543 | * | |
544 | * @return String el that should evaluate to boolean | |
545 | */ | |
546 | public String getConditionalRenderSequenceField() { | |
547 | 0 | return this.conditionalRenderSequenceField; |
548 | } | |
549 | ||
550 | /** | |
551 | * Setter for the conditional render sequence field string | |
552 | * | |
553 | * @param conditionalRenderSequenceField | |
554 | */ | |
555 | public void setConditionalRenderSequenceField(String conditionalRenderSequenceField) { | |
556 | 0 | this.conditionalRenderSequenceField = conditionalRenderSequenceField; |
557 | 0 | } |
558 | ||
559 | /** | |
560 | * Attribute name to use as sequence value. For each collection line the | |
561 | * value of this field on the line will be retrieved and used as the | |
562 | * sequence value | |
563 | * | |
564 | * @return String sequence property name | |
565 | */ | |
566 | public String getSequencePropertyName() { | |
567 | 0 | if (sequenceFieldPrototype != null) { |
568 | 0 | return sequenceFieldPrototype.getPropertyName(); |
569 | } | |
570 | ||
571 | 0 | return null; |
572 | } | |
573 | ||
574 | /** | |
575 | * Setter for the sequence property name | |
576 | * | |
577 | * @param sequencePropertyName | |
578 | */ | |
579 | public void setSequencePropertyName(String sequencePropertyName) { | |
580 | 0 | if (sequenceFieldPrototype != null) { |
581 | 0 | sequenceFieldPrototype.setPropertyName(sequencePropertyName); |
582 | } | |
583 | 0 | } |
584 | ||
585 | /** | |
586 | * <code>AttributeField</code> instance to serve as a prototype for the | |
587 | * sequence field. For each collection line this instance is copied and | |
588 | * adjusted as necessary | |
589 | * | |
590 | * @return Attribute field instance | |
591 | */ | |
592 | public AttributeField getSequenceFieldPrototype() { | |
593 | 0 | return this.sequenceFieldPrototype; |
594 | } | |
595 | ||
596 | /** | |
597 | * Setter for the sequence field prototype | |
598 | * | |
599 | * @param sequenceFieldPrototype | |
600 | */ | |
601 | public void setSequenceFieldPrototype(AttributeField sequenceFieldPrototype) { | |
602 | 0 | this.sequenceFieldPrototype = sequenceFieldPrototype; |
603 | 0 | } |
604 | ||
605 | /** | |
606 | * <code>GroupField</code> instance to serve as a prototype for the actions | |
607 | * column. For each collection line this instance is copied and adjusted as | |
608 | * necessary. Note the actual actions for the group come from the collection | |
609 | * groups actions List | |
610 | * (org.kuali.rice.kns.uif.container.CollectionGroup.getActionFields()). The | |
611 | * GroupField prototype is useful for setting styling of the actions column | |
612 | * and for the layout of the action fields. Note also the label associated | |
613 | * with the prototype is used for the action column header | |
614 | * | |
615 | * @return GroupField instance | |
616 | */ | |
617 | public GroupField getActionFieldPrototype() { | |
618 | 0 | return this.actionFieldPrototype; |
619 | } | |
620 | ||
621 | /** | |
622 | * Setter for the action field prototype | |
623 | * | |
624 | * @param actionFieldPrototype | |
625 | */ | |
626 | public void setActionFieldPrototype(GroupField actionFieldPrototype) { | |
627 | 0 | this.actionFieldPrototype = actionFieldPrototype; |
628 | 0 | } |
629 | ||
630 | /** | |
631 | * @see org.kuali.rice.kns.uif.layout.CollectionLayoutManager#getSubCollectionGroupFieldPrototype() | |
632 | */ | |
633 | public GroupField getSubCollectionGroupFieldPrototype() { | |
634 | 0 | return this.subCollectionGroupFieldPrototype; |
635 | } | |
636 | ||
637 | /** | |
638 | * Setter for the sub-collection field group prototype | |
639 | * | |
640 | * @param subCollectionGroupFieldPrototype | |
641 | */ | |
642 | public void setSubCollectionGroupFieldPrototype(GroupField subCollectionGroupFieldPrototype) { | |
643 | 0 | this.subCollectionGroupFieldPrototype = subCollectionGroupFieldPrototype; |
644 | 0 | } |
645 | ||
646 | /** | |
647 | * List of <code>Field</code> instances that make up the tables body. Pulled | |
648 | * by the layout manager template to send through the Grid layout | |
649 | * | |
650 | * @return List<Field> table body fields | |
651 | */ | |
652 | public List<Field> getDataFields() { | |
653 | 0 | return this.dataFields; |
654 | } | |
655 | ||
656 | /** | |
657 | * Widget associated with the table to add functionality such as sorting, | |
658 | * paging, and export | |
659 | * | |
660 | * @return TableTools instance | |
661 | */ | |
662 | public TableTools getTableTools() { | |
663 | 0 | return this.tableTools; |
664 | } | |
665 | ||
666 | /** | |
667 | * Setter for the table tools widget | |
668 | * | |
669 | * @param tableTools | |
670 | */ | |
671 | public void setTableTools(TableTools tableTools) { | |
672 | 0 | this.tableTools = tableTools; |
673 | 0 | } |
674 | ||
675 | /** | |
676 | * @return the numberOfDataColumns | |
677 | */ | |
678 | public int getNumberOfDataColumns() { | |
679 | 0 | if (isMatchColumnsToFieldCount()) { |
680 | 0 | return getNumberOfColumns(); |
681 | } | |
682 | 0 | return this.numberOfDataColumns; |
683 | } | |
684 | ||
685 | /** | |
686 | * @param numberOfDataColumns the numberOfDataColumns to set | |
687 | */ | |
688 | public void setNumberOfDataColumns(int numberOfDataColumns) { | |
689 | 0 | this.numberOfDataColumns = numberOfDataColumns; |
690 | 0 | } |
691 | ||
692 | } |