Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TableLayoutManager |
|
| 2.375;2.375 |
1 | /** | |
2 | * Copyright 2005-2011 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.apache.commons.lang.StringUtils; | |
19 | import org.kuali.rice.krad.uif.UifConstants; | |
20 | import org.kuali.rice.krad.uif.component.DataBinding; | |
21 | import org.kuali.rice.krad.uif.container.CollectionGroup; | |
22 | import org.kuali.rice.krad.uif.container.Container; | |
23 | import org.kuali.rice.krad.uif.container.Group; | |
24 | import org.kuali.rice.krad.uif.field.DataField; | |
25 | import org.kuali.rice.krad.uif.field.FieldGroup; | |
26 | import org.kuali.rice.krad.uif.field.InputField; | |
27 | import org.kuali.rice.krad.uif.view.View; | |
28 | import org.kuali.rice.krad.uif.component.Component; | |
29 | import org.kuali.rice.krad.uif.field.ActionField; | |
30 | import org.kuali.rice.krad.uif.field.Field; | |
31 | import org.kuali.rice.krad.uif.field.LabelField; | |
32 | import org.kuali.rice.krad.uif.field.MessageField; | |
33 | import org.kuali.rice.krad.uif.util.ComponentFactory; | |
34 | import org.kuali.rice.krad.uif.util.ComponentUtils; | |
35 | import org.kuali.rice.krad.uif.widget.RichTable; | |
36 | import org.kuali.rice.krad.web.form.UifFormBase; | |
37 | ||
38 | import java.util.ArrayList; | |
39 | import java.util.List; | |
40 | ||
41 | /** | |
42 | * Layout manager that works with <code>CollectionGroup</code> components and | |
43 | * renders the collection as a Table | |
44 | * | |
45 | * <p> | |
46 | * Based on the fields defined, the <code>TableLayoutManager</code> will | |
47 | * dynamically create instances of the fields for each collection row. In | |
48 | * addition, the manager can create standard fields like the action and sequence | |
49 | * fields for each row. The manager supports options inherited from the | |
50 | * <code>GridLayoutManager</code> such as rowSpan, colSpan, and cell width | |
51 | * settings. | |
52 | * </p> | |
53 | * | |
54 | * @author Kuali Rice Team (rice.collab@kuali.org) | |
55 | */ | |
56 | public class TableLayoutManager extends GridLayoutManager implements CollectionLayoutManager { | |
57 | private static final long serialVersionUID = 3622267585541524208L; | |
58 | ||
59 | private boolean useShortLabels; | |
60 | private boolean repeatHeader; | |
61 | private LabelField headerFieldPrototype; | |
62 | ||
63 | private boolean renderSequenceField; | |
64 | private boolean generateAutoSequence; | |
65 | private Field sequenceFieldPrototype; | |
66 | ||
67 | private FieldGroup actionFieldPrototype; | |
68 | private FieldGroup subCollectionFieldGroupPrototype; | |
69 | private Field selectFieldPrototype; | |
70 | ||
71 | private boolean separateAddLine; | |
72 | private Group addLineGroup; | |
73 | ||
74 | // internal counter for the data columns (not including sequence, action) | |
75 | private int numberOfDataColumns; | |
76 | ||
77 | private List<LabelField> headerFields; | |
78 | private List<Field> dataFields; | |
79 | ||
80 | private RichTable richTable; | |
81 | 0 | private boolean headerAdded = false; |
82 | ||
83 | 0 | public TableLayoutManager() { |
84 | 0 | useShortLabels = true; |
85 | 0 | repeatHeader = false; |
86 | 0 | renderSequenceField = true; |
87 | 0 | generateAutoSequence = false; |
88 | 0 | separateAddLine = false; |
89 | ||
90 | 0 | headerFields = new ArrayList<LabelField>(); |
91 | 0 | dataFields = new ArrayList<Field>(); |
92 | 0 | } |
93 | ||
94 | /** | |
95 | * The following actions are performed: | |
96 | * | |
97 | * <ul> | |
98 | * <li>Sets sequence field prototype if auto sequence is true</li> | |
99 | * <li>Initializes the prototypes</li> | |
100 | * </ul> | |
101 | * | |
102 | * @see org.kuali.rice.krad.uif.layout.BoxLayoutManager#performInitialization(org.kuali.rice.krad.uif.view.View, | |
103 | * java.lang.Object, org.kuali.rice.krad.uif.container.Container) | |
104 | */ | |
105 | @Override | |
106 | public void performInitialization(View view, Object model, Container container) { | |
107 | 0 | super.performInitialization(view, model, container); |
108 | ||
109 | 0 | if (generateAutoSequence && !(sequenceFieldPrototype instanceof MessageField)) { |
110 | 0 | sequenceFieldPrototype = ComponentFactory.getMessageField(); |
111 | 0 | view.assignComponentIds(sequenceFieldPrototype); |
112 | } | |
113 | ||
114 | 0 | view.getViewHelperService().performComponentInitialization(view, model, headerFieldPrototype); |
115 | 0 | view.getViewHelperService().performComponentInitialization(view, model, sequenceFieldPrototype); |
116 | 0 | view.getViewHelperService().performComponentInitialization(view, model, actionFieldPrototype); |
117 | 0 | view.getViewHelperService().performComponentInitialization(view, model, subCollectionFieldGroupPrototype); |
118 | 0 | view.getViewHelperService().performComponentInitialization(view, model, selectFieldPrototype); |
119 | 0 | } |
120 | ||
121 | /** | |
122 | * Sets up the final column count for rendering based on whether the | |
123 | * sequence and action fields have been generated | |
124 | * | |
125 | * @see org.kuali.rice.krad.uif.layout.LayoutManagerBase#performFinalize(org.kuali.rice.krad.uif.view.View, | |
126 | * java.lang.Object, org.kuali.rice.krad.uif.container.Container) | |
127 | */ | |
128 | @Override | |
129 | public void performFinalize(View view, Object model, Container container) { | |
130 | 0 | super.performFinalize(view, model, container); |
131 | ||
132 | 0 | UifFormBase formBase = (UifFormBase) model; |
133 | ||
134 | 0 | CollectionGroup collectionGroup = (CollectionGroup) container; |
135 | ||
136 | 0 | int totalColumns = getNumberOfDataColumns(); |
137 | 0 | if (renderSequenceField) { |
138 | 0 | totalColumns++; |
139 | } | |
140 | ||
141 | 0 | if (collectionGroup.isRenderSelectField()) { |
142 | 0 | totalColumns++; |
143 | } | |
144 | ||
145 | 0 | if (collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly()) { |
146 | 0 | totalColumns++; |
147 | } | |
148 | ||
149 | 0 | if (collectionGroup.isRenderAddLine()){ |
150 | 0 | if(StringUtils.isBlank(this.getFirstLineStyle()) && !isSeparateAddLine()){ |
151 | 0 | this.setFirstLineStyle("kr-addLine"); |
152 | } | |
153 | } | |
154 | ||
155 | // if add line event, add highlighting for added row | |
156 | 0 | if (UifConstants.ActionEvents.ADD_LINE.equals(formBase.getActionEvent())) { |
157 | 0 | String highlightScript = |
158 | "jq(\"#" + container.getId() + "_div > tr:first\").effect(\"highlight\",{}, 6000);"; | |
159 | 0 | String onReadyScript = collectionGroup.getOnDocumentReadyScript(); |
160 | 0 | if (StringUtils.isNotBlank(onReadyScript)) { |
161 | 0 | highlightScript = onReadyScript + highlightScript; |
162 | } | |
163 | 0 | collectionGroup.setOnDocumentReadyScript(highlightScript); |
164 | } | |
165 | 0 | setNumberOfColumns(totalColumns); |
166 | 0 | } |
167 | ||
168 | /** | |
169 | * Assembles the field instances for the collection line. The given sequence | |
170 | * field prototype is copied for the line sequence field. Likewise a copy of | |
171 | * the actionFieldPrototype is made and the given actions are set as the | |
172 | * items for the action field. Finally the generated items are assembled | |
173 | * together into the dataFields list with the given lineFields. | |
174 | * | |
175 | * @see org.kuali.rice.krad.uif.layout.CollectionLayoutManager#buildLine(org.kuali.rice.krad.uif.view.View, | |
176 | * java.lang.Object, org.kuali.rice.krad.uif.container.CollectionGroup, | |
177 | * java.util.List, java.util.List, java.lang.String, java.util.List, | |
178 | * java.lang.String, java.lang.Object, int) | |
179 | */ | |
180 | public void buildLine(View view, Object model, CollectionGroup collectionGroup, List<Field> lineFields, | |
181 | List<FieldGroup> subCollectionFields, String bindingPath, List<ActionField> actions, String idSuffix, | |
182 | Object currentLine, int lineIndex) { | |
183 | 0 | boolean isAddLine = lineIndex == -1; |
184 | ||
185 | // if separate add line prepare the add line group | |
186 | 0 | if (isAddLine && separateAddLine) { |
187 | 0 | if (StringUtils.isBlank(addLineGroup.getTitle()) && StringUtils.isBlank( |
188 | addLineGroup.getHeader().getHeaderText())) { | |
189 | 0 | addLineGroup.getHeader().setHeaderText(collectionGroup.getAddLineLabel()); |
190 | } | |
191 | ||
192 | 0 | addLineGroup.setItems(lineFields); |
193 | ||
194 | 0 | List<Component> footerItems = new ArrayList<Component>(actions); |
195 | 0 | footerItems.addAll(addLineGroup.getFooter().getItems()); |
196 | 0 | addLineGroup.getFooter().setItems(footerItems); |
197 | ||
198 | 0 | return; |
199 | } | |
200 | ||
201 | // if add line or first line set number of data columns | |
202 | 0 | if (isAddLine || ((!collectionGroup.isRenderAddLine() || collectionGroup.isReadOnly() || isSeparateAddLine()) |
203 | && (lineIndex == 0))) { | |
204 | 0 | if (isSuppressLineWrapping()) { |
205 | 0 | setNumberOfDataColumns(lineFields.size()); |
206 | } else { | |
207 | 0 | setNumberOfDataColumns(getNumberOfColumns()); |
208 | } | |
209 | } | |
210 | ||
211 | // TODO: implement repeat header | |
212 | 0 | if (!headerAdded) { |
213 | 0 | headerFields = new ArrayList<LabelField>(); |
214 | 0 | dataFields = new ArrayList<Field>(); |
215 | ||
216 | 0 | buildTableHeaderRows(collectionGroup, lineFields); |
217 | 0 | ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.LINE, currentLine); |
218 | 0 | ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.INDEX, new Integer( |
219 | lineIndex)); | |
220 | 0 | headerAdded = true; |
221 | } | |
222 | ||
223 | // set label field rendered to true on line fields | |
224 | 0 | for (Field field : lineFields) { |
225 | 0 | field.setLabelFieldRendered(true); |
226 | ||
227 | // don't display summary message | |
228 | // TODO: remove once we have modifier | |
229 | 0 | ComponentUtils.setComponentPropertyDeep(field, "summaryMessageField.render", new Boolean(false)); |
230 | } | |
231 | ||
232 | 0 | int rowCount = calculateNumberOfRows(collectionGroup.getItems()); |
233 | 0 | int rowSpan = rowCount + subCollectionFields.size(); |
234 | ||
235 | // sequence field is always first and should span all rows for the line | |
236 | 0 | if (renderSequenceField) { |
237 | 0 | Field sequenceField = null; |
238 | 0 | if (!isAddLine) { |
239 | 0 | sequenceField = ComponentUtils.copy(sequenceFieldPrototype, idSuffix); |
240 | ||
241 | 0 | if (generateAutoSequence && (sequenceField instanceof MessageField)) { |
242 | 0 | ((MessageField) sequenceField).setMessageText(Integer.toString(lineIndex + 1)); |
243 | } | |
244 | } | |
245 | else { | |
246 | 0 | sequenceField = ComponentUtils.copy(collectionGroup.getAddLineLabelField(), idSuffix); |
247 | } | |
248 | 0 | sequenceField.setRowSpan(rowSpan); |
249 | ||
250 | 0 | if (sequenceField instanceof DataBinding) { |
251 | 0 | ((DataBinding) sequenceField).getBindingInfo().setBindByNamePrefix(bindingPath); |
252 | } | |
253 | ||
254 | 0 | ComponentUtils.updateContextForLine(sequenceField, currentLine, lineIndex); |
255 | 0 | dataFields.add(sequenceField); |
256 | } | |
257 | ||
258 | // select field will come after sequence field (if enabled) or be first column | |
259 | 0 | if (collectionGroup.isRenderSelectField()) { |
260 | 0 | Field selectField = ComponentUtils.copy(selectFieldPrototype, idSuffix); |
261 | 0 | CollectionLayoutUtils.prepareSelectFieldForLine(selectField, collectionGroup, bindingPath, currentLine); |
262 | ||
263 | 0 | ComponentUtils.updateContextForLine(selectField, currentLine, lineIndex); |
264 | 0 | dataFields.add(selectField); |
265 | } | |
266 | ||
267 | // now add the fields in the correct position | |
268 | 0 | int cellPosition = 0; |
269 | 0 | for (Field lineField : lineFields) { |
270 | 0 | dataFields.add(lineField); |
271 | ||
272 | 0 | cellPosition += lineField.getColSpan(); |
273 | ||
274 | // action field should be in last column | |
275 | 0 | if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions() |
276 | && !collectionGroup.isReadOnly()) { | |
277 | 0 | FieldGroup lineActionsField = ComponentUtils.copy(actionFieldPrototype, idSuffix); |
278 | ||
279 | 0 | ComponentUtils.updateContextForLine(lineActionsField, currentLine, lineIndex); |
280 | 0 | lineActionsField.setRowSpan(rowSpan); |
281 | 0 | lineActionsField.setItems(actions); |
282 | ||
283 | 0 | dataFields.add(lineActionsField); |
284 | 0 | } |
285 | } | |
286 | ||
287 | // update colspan on sub-collection fields | |
288 | 0 | for (FieldGroup subCollectionField : subCollectionFields) { |
289 | 0 | subCollectionField.setColSpan(numberOfDataColumns); |
290 | } | |
291 | ||
292 | // add sub-collection fields to end of data fields | |
293 | 0 | dataFields.addAll(subCollectionFields); |
294 | 0 | } |
295 | ||
296 | /** | |
297 | * Create the <code>LabelField</code> instances that will be used to render | |
298 | * the table header | |
299 | * | |
300 | * <p> | |
301 | * For each column, a copy of headerFieldPrototype is made that determines | |
302 | * the label configuration. The actual label text comes from the field for | |
303 | * which the header applies to. The first column is always the sequence (if | |
304 | * enabled) and the last column contains the actions. Both the sequence and | |
305 | * action header fields will span all rows for the header. | |
306 | * </p> | |
307 | * | |
308 | * <p> | |
309 | * The headerFields list will contain the final list of header fields built | |
310 | * </p> | |
311 | * | |
312 | * @param collectionGroup | |
313 | * - CollectionGroup container the table applies to | |
314 | * @param lineFields - fields for the data columns from which the headers are pulled | |
315 | */ | |
316 | protected void buildTableHeaderRows(CollectionGroup collectionGroup, List<Field> lineFields) { | |
317 | // row count needed to determine the row span for the sequence and | |
318 | // action fields, since they should span all rows for the line | |
319 | 0 | int rowCount = calculateNumberOfRows(collectionGroup.getItems()); |
320 | ||
321 | // first column is sequence label | |
322 | 0 | if (renderSequenceField) { |
323 | 0 | sequenceFieldPrototype.setLabelFieldRendered(true); |
324 | 0 | sequenceFieldPrototype.setRowSpan(rowCount); |
325 | 0 | addHeaderField(sequenceFieldPrototype, 1); |
326 | } | |
327 | ||
328 | // next is select field | |
329 | 0 | if (collectionGroup.isRenderSelectField()) { |
330 | 0 | selectFieldPrototype.setLabelFieldRendered(true); |
331 | 0 | selectFieldPrototype.setRowSpan(rowCount); |
332 | 0 | addHeaderField(selectFieldPrototype, 1); |
333 | } | |
334 | ||
335 | // pull out label fields from the container's items | |
336 | 0 | int cellPosition = 0; |
337 | 0 | for (Field field : lineFields) { |
338 | 0 | if (!field.isRender() && StringUtils.isEmpty(field.getProgressiveRender())) { |
339 | 0 | continue; |
340 | } | |
341 | ||
342 | 0 | cellPosition += field.getColSpan(); |
343 | 0 | addHeaderField(field, cellPosition); |
344 | ||
345 | // add action header as last column in row | |
346 | 0 | if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions() |
347 | && !collectionGroup.isReadOnly()) { | |
348 | 0 | actionFieldPrototype.setLabelFieldRendered(true); |
349 | 0 | actionFieldPrototype.setRowSpan(rowCount); |
350 | 0 | addHeaderField(actionFieldPrototype, cellPosition); |
351 | } | |
352 | } | |
353 | 0 | } |
354 | ||
355 | /** | |
356 | * Creates a new instance of the header field prototype and then sets the | |
357 | * label to the short (if useShortLabels is set to true) or long label of | |
358 | * the given component. After created the header field is added to the list | |
359 | * making up the table header | |
360 | * | |
361 | * @param field | |
362 | * - field instance the header field is being created for | |
363 | * @param column | |
364 | * - column number for the header, used for setting the id | |
365 | */ | |
366 | protected void addHeaderField(Field field, int column) { | |
367 | 0 | LabelField headerField = ComponentUtils.copy(headerFieldPrototype, "_c" + column); |
368 | 0 | if (useShortLabels) { |
369 | 0 | headerField.setLabelText(field.getLabel()); |
370 | } | |
371 | else { | |
372 | 0 | headerField.setLabelText(field.getLabel()); |
373 | } | |
374 | ||
375 | 0 | headerField.setRowSpan(field.getRowSpan()); |
376 | 0 | headerField.setColSpan(field.getColSpan()); |
377 | ||
378 | 0 | if ((field.getRequired() != null) && field.getRequired().booleanValue()) { |
379 | 0 | headerField.getRequiredMessageField().setRender(true); |
380 | } | |
381 | else { | |
382 | 0 | headerField.getRequiredMessageField().setRender(false); |
383 | } | |
384 | ||
385 | 0 | headerFields.add(headerField); |
386 | 0 | } |
387 | ||
388 | /** | |
389 | * Calculates how many rows will be needed per collection line to display | |
390 | * the list of fields. Assumption is made that the total number of cells the | |
391 | * fields take up is evenly divisible by the configured number of columns | |
392 | * | |
393 | * @param items | |
394 | * - list of items that make up one collection line | |
395 | * @return int number of rows | |
396 | */ | |
397 | protected int calculateNumberOfRows(List<? extends Field> items) { | |
398 | 0 | int rowCount = 0; |
399 | ||
400 | // check flag that indicates only one row should be created | |
401 | 0 | if (isSuppressLineWrapping()) { |
402 | 0 | return 1; |
403 | } | |
404 | ||
405 | 0 | int cellCount = 0; |
406 | 0 | for (Field field : items) { |
407 | 0 | cellCount += field.getColSpan() + field.getRowSpan() - 1; |
408 | } | |
409 | ||
410 | 0 | if (cellCount != 0) { |
411 | 0 | rowCount = cellCount / getNumberOfDataColumns(); |
412 | } | |
413 | ||
414 | 0 | return rowCount; |
415 | } | |
416 | ||
417 | /** | |
418 | * @see org.kuali.rice.krad.uif.layout.ContainerAware#getSupportedContainer() | |
419 | */ | |
420 | @Override | |
421 | public Class<? extends Container> getSupportedContainer() { | |
422 | 0 | return CollectionGroup.class; |
423 | } | |
424 | ||
425 | /** | |
426 | * @see org.kuali.rice.krad.uif.layout.LayoutManagerBase#getComponentsForLifecycle() | |
427 | */ | |
428 | @Override | |
429 | public List<Component> getComponentsForLifecycle() { | |
430 | 0 | List<Component> components = super.getComponentsForLifecycle(); |
431 | ||
432 | 0 | components.add(richTable); |
433 | 0 | components.add(addLineGroup); |
434 | 0 | components.addAll(headerFields); |
435 | 0 | components.addAll(dataFields); |
436 | ||
437 | 0 | return components; |
438 | } | |
439 | ||
440 | /** | |
441 | * @see org.kuali.rice.krad.uif.layout.LayoutManager#getComponentPrototypes() | |
442 | */ | |
443 | @Override | |
444 | public List<Component> getComponentPrototypes() { | |
445 | 0 | List<Component> components = super.getComponentPrototypes(); |
446 | ||
447 | 0 | components.add(headerFieldPrototype); |
448 | 0 | components.add(sequenceFieldPrototype); |
449 | 0 | components.add(actionFieldPrototype); |
450 | 0 | components.add(subCollectionFieldGroupPrototype); |
451 | 0 | components.add(selectFieldPrototype); |
452 | ||
453 | 0 | return components; |
454 | } | |
455 | ||
456 | /** | |
457 | * Indicates whether the short label for the collection field should be used | |
458 | * as the table header or the regular label | |
459 | * | |
460 | * @return boolean true if short label should be used, false if long label | |
461 | * should be used | |
462 | */ | |
463 | public boolean isUseShortLabels() { | |
464 | 0 | return this.useShortLabels; |
465 | } | |
466 | ||
467 | /** | |
468 | * Setter for the use short label indicator | |
469 | * | |
470 | * @param useShortLabels | |
471 | */ | |
472 | public void setUseShortLabels(boolean useShortLabels) { | |
473 | 0 | this.useShortLabels = useShortLabels; |
474 | 0 | } |
475 | ||
476 | /** | |
477 | * Indicates whether the header should be repeated before each collection | |
478 | * row. If false the header is only rendered at the beginning of the table | |
479 | * | |
480 | * @return boolean true if header should be repeated, false if it should | |
481 | * only be rendered once | |
482 | */ | |
483 | public boolean isRepeatHeader() { | |
484 | 0 | return this.repeatHeader; |
485 | } | |
486 | ||
487 | /** | |
488 | * Setter for the repeat header indicator | |
489 | * | |
490 | * @param repeatHeader | |
491 | */ | |
492 | public void setRepeatHeader(boolean repeatHeader) { | |
493 | 0 | this.repeatHeader = repeatHeader; |
494 | 0 | } |
495 | ||
496 | /** | |
497 | * <code>LabelField</code> instance to use as a prototype for creating the | |
498 | * tables header fields. For each header field the prototype will be copied | |
499 | * and adjusted as necessary | |
500 | * | |
501 | * @return LabelField instance to serve as prototype | |
502 | */ | |
503 | public LabelField getHeaderFieldPrototype() { | |
504 | 0 | return this.headerFieldPrototype; |
505 | } | |
506 | ||
507 | /** | |
508 | * Setter for the header field prototype | |
509 | * | |
510 | * @param headerFieldPrototype | |
511 | */ | |
512 | public void setHeaderFieldPrototype(LabelField headerFieldPrototype) { | |
513 | 0 | this.headerFieldPrototype = headerFieldPrototype; |
514 | 0 | } |
515 | ||
516 | /** | |
517 | * List of <code>LabelField</code> instances that should be rendered to make | |
518 | * up the tables header | |
519 | * | |
520 | * @return List of label field instances | |
521 | */ | |
522 | public List<LabelField> getHeaderFields() { | |
523 | 0 | return this.headerFields; |
524 | } | |
525 | ||
526 | /** | |
527 | * Indicates whether the sequence field should be rendered for the | |
528 | * collection | |
529 | * | |
530 | * @return boolean true if sequence field should be rendered, false if not | |
531 | */ | |
532 | public boolean isRenderSequenceField() { | |
533 | 0 | return this.renderSequenceField; |
534 | } | |
535 | ||
536 | /** | |
537 | * Setter for the render sequence field indicator | |
538 | * | |
539 | * @param renderSequenceField | |
540 | */ | |
541 | public void setRenderSequenceField(boolean renderSequenceField) { | |
542 | 0 | this.renderSequenceField = renderSequenceField; |
543 | 0 | } |
544 | ||
545 | /** | |
546 | * Attribute name to use as sequence value. For each collection line the | |
547 | * value of this field on the line will be retrieved and used as the | |
548 | * sequence value | |
549 | * | |
550 | * @return String sequence property name | |
551 | */ | |
552 | public String getSequencePropertyName() { | |
553 | 0 | if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) { |
554 | 0 | return ((DataField) sequenceFieldPrototype).getPropertyName(); |
555 | } | |
556 | ||
557 | 0 | return null; |
558 | } | |
559 | ||
560 | /** | |
561 | * Setter for the sequence property name | |
562 | * | |
563 | * @param sequencePropertyName | |
564 | */ | |
565 | public void setSequencePropertyName(String sequencePropertyName) { | |
566 | 0 | if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) { |
567 | 0 | ((DataField) sequenceFieldPrototype).setPropertyName(sequencePropertyName); |
568 | } | |
569 | 0 | } |
570 | ||
571 | /** | |
572 | * Indicates whether the sequence field should be generated with the current | |
573 | * line number | |
574 | * | |
575 | * <p> | |
576 | * If set to true the sequence field prototype will be changed to a message | |
577 | * field (if not already a message field) and the text will be set to the | |
578 | * current line number | |
579 | * </p> | |
580 | * | |
581 | * @return boolean true if the sequence field should be generated from the | |
582 | * line number, false if not | |
583 | */ | |
584 | public boolean isGenerateAutoSequence() { | |
585 | 0 | return this.generateAutoSequence; |
586 | } | |
587 | ||
588 | /** | |
589 | * Setter for the generate auto sequence field | |
590 | * | |
591 | * @param generateAutoSequence | |
592 | */ | |
593 | public void setGenerateAutoSequence(boolean generateAutoSequence) { | |
594 | 0 | this.generateAutoSequence = generateAutoSequence; |
595 | 0 | } |
596 | ||
597 | /** | |
598 | * <code>Field</code> instance to serve as a prototype for the | |
599 | * sequence field. For each collection line this instance is copied and | |
600 | * adjusted as necessary | |
601 | * | |
602 | * @return Attribute field instance | |
603 | */ | |
604 | public Field getSequenceFieldPrototype() { | |
605 | 0 | return this.sequenceFieldPrototype; |
606 | } | |
607 | ||
608 | /** | |
609 | * Setter for the sequence field prototype | |
610 | * | |
611 | * @param sequenceFieldPrototype | |
612 | */ | |
613 | public void setSequenceFieldPrototype(Field sequenceFieldPrototype) { | |
614 | 0 | this.sequenceFieldPrototype = sequenceFieldPrototype; |
615 | 0 | } |
616 | ||
617 | /** | |
618 | * <code>FieldGroup</code> instance to serve as a prototype for the actions | |
619 | * column. For each collection line this instance is copied and adjusted as | |
620 | * necessary. Note the actual actions for the group come from the collection | |
621 | * groups actions List | |
622 | * (org.kuali.rice.krad.uif.container.CollectionGroup.getActionFields()). The | |
623 | * FieldGroup prototype is useful for setting styling of the actions column | |
624 | * and for the layout of the action fields. Note also the label associated | |
625 | * with the prototype is used for the action column header | |
626 | * | |
627 | * @return GroupField instance | |
628 | */ | |
629 | public FieldGroup getActionFieldPrototype() { | |
630 | 0 | return this.actionFieldPrototype; |
631 | } | |
632 | ||
633 | /** | |
634 | * Setter for the action field prototype | |
635 | * | |
636 | * @param actionFieldPrototype | |
637 | */ | |
638 | public void setActionFieldPrototype(FieldGroup actionFieldPrototype) { | |
639 | 0 | this.actionFieldPrototype = actionFieldPrototype; |
640 | 0 | } |
641 | ||
642 | /** | |
643 | * @see org.kuali.rice.krad.uif.layout.CollectionLayoutManager#getSubCollectionFieldGroupPrototype() | |
644 | */ | |
645 | public FieldGroup getSubCollectionFieldGroupPrototype() { | |
646 | 0 | return this.subCollectionFieldGroupPrototype; |
647 | } | |
648 | ||
649 | /** | |
650 | * Setter for the sub-collection field group prototype | |
651 | * | |
652 | * @param subCollectionFieldGroupPrototype | |
653 | */ | |
654 | public void setSubCollectionFieldGroupPrototype(FieldGroup subCollectionFieldGroupPrototype) { | |
655 | 0 | this.subCollectionFieldGroupPrototype = subCollectionFieldGroupPrototype; |
656 | 0 | } |
657 | ||
658 | /** | |
659 | * Field instance that serves as a prototype for creating the select field on each line when | |
660 | * {@link org.kuali.rice.krad.uif.container.CollectionGroup#isRenderSelectField()} is true | |
661 | * | |
662 | * <p> | |
663 | * This prototype can be used to set the control used for the select field (generally will be a checkbox control) | |
664 | * in addition to styling and other setting. The binding path will be formed with using the | |
665 | * {@link org.kuali.rice.krad.uif.container.CollectionGroup#getSelectPropertyName()} or if not set the framework | |
666 | * will use {@link org.kuali.rice.krad.web.form.UifFormBase#getSelectedCollectionLines()} | |
667 | * </p> | |
668 | * | |
669 | * @return Field select field prototype instance | |
670 | */ | |
671 | public Field getSelectFieldPrototype() { | |
672 | 0 | return selectFieldPrototype; |
673 | } | |
674 | ||
675 | /** | |
676 | * Setter for the prototype instance for select fields | |
677 | * | |
678 | * @param selectFieldPrototype | |
679 | */ | |
680 | public void setSelectFieldPrototype(Field selectFieldPrototype) { | |
681 | 0 | this.selectFieldPrototype = selectFieldPrototype; |
682 | 0 | } |
683 | ||
684 | /** | |
685 | * Indicates whether the add line should be rendered in a separate group, or as part of the table (first line) | |
686 | * | |
687 | * <p> | |
688 | * When separate add line is enabled, the fields for the add line will be placed in the {@link #getAddLineGroup()}. | |
689 | * This group can be used to configure the add line presentation. In addition to the fields, the header on the | |
690 | * group (unless already set) will be set to | |
691 | * {@link org.kuali.rice.krad.uif.container.CollectionGroup#getAddLineLabel()} and the add line actions will | |
692 | * be placed into the group's footer. | |
693 | * </p> | |
694 | * | |
695 | * @return boolean true if add line should be separated, false if it should be placed into the table | |
696 | */ | |
697 | public boolean isSeparateAddLine() { | |
698 | 0 | return separateAddLine; |
699 | } | |
700 | ||
701 | /** | |
702 | * Setter for the separate add line indicator | |
703 | * | |
704 | * @param separateAddLine | |
705 | */ | |
706 | public void setSeparateAddLine(boolean separateAddLine) { | |
707 | 0 | this.separateAddLine = separateAddLine; |
708 | 0 | } |
709 | ||
710 | /** | |
711 | * When {@link #isSeparateAddLine()} is true, this group will be used to render the add line | |
712 | * | |
713 | * <p> | |
714 | * This group can be used to configure how the add line will be rendered. For example the layout manager configured | |
715 | * on the group will be used to rendered the add line fields. If the header (title) is not set on the group, it | |
716 | * will be set from | |
717 | * {@link org.kuali.rice.krad.uif.container.CollectionGroup#getAddLineLabel()}. In addition, | |
718 | * {@link org.kuali.rice.krad.uif.container.CollectionGroup#getAddLineActionFields()} will be added to the group | |
719 | * footer items. | |
720 | * </p> | |
721 | * | |
722 | * @return Group instance for the collection add line | |
723 | */ | |
724 | public Group getAddLineGroup() { | |
725 | 0 | return addLineGroup; |
726 | } | |
727 | ||
728 | /** | |
729 | * Setter for the add line Group | |
730 | * | |
731 | * @param addLineGroup | |
732 | */ | |
733 | public void setAddLineGroup(Group addLineGroup) { | |
734 | 0 | this.addLineGroup = addLineGroup; |
735 | 0 | } |
736 | ||
737 | /** | |
738 | * List of <code>Field</code> instances that make up the tables body. Pulled | |
739 | * by the layout manager template to send through the Grid layout | |
740 | * | |
741 | * @return List<Field> table body fields | |
742 | */ | |
743 | public List<Field> getDataFields() { | |
744 | 0 | return this.dataFields; |
745 | } | |
746 | ||
747 | /** | |
748 | * Widget associated with the table to add functionality such as sorting, | |
749 | * paging, and export | |
750 | * | |
751 | * @return TableTools instance | |
752 | */ | |
753 | public RichTable getRichTable() { | |
754 | 0 | return this.richTable; |
755 | } | |
756 | ||
757 | /** | |
758 | * Setter for the table tools widget | |
759 | * | |
760 | * @param richTable | |
761 | */ | |
762 | public void setRichTable(RichTable richTable) { | |
763 | 0 | this.richTable = richTable; |
764 | 0 | } |
765 | ||
766 | /** | |
767 | * @return the numberOfDataColumns | |
768 | */ | |
769 | public int getNumberOfDataColumns() { | |
770 | 0 | return this.numberOfDataColumns; |
771 | } | |
772 | ||
773 | /** | |
774 | * @param numberOfDataColumns the numberOfDataColumns to set | |
775 | */ | |
776 | public void setNumberOfDataColumns(int numberOfDataColumns) { | |
777 | 0 | this.numberOfDataColumns = numberOfDataColumns; |
778 | 0 | } |
779 | ||
780 | } |