1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.layout;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.TreeMap;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
27 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
28 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
29 import org.kuali.rice.krad.uif.CssConstants;
30 import org.kuali.rice.krad.uif.UifConstants;
31 import org.kuali.rice.krad.uif.UifPropertyPaths;
32 import org.kuali.rice.krad.uif.component.Component;
33 import org.kuali.rice.krad.uif.component.DataBinding;
34 import org.kuali.rice.krad.uif.component.KeepExpression;
35 import org.kuali.rice.krad.uif.container.CollectionGroup;
36 import org.kuali.rice.krad.uif.container.Container;
37 import org.kuali.rice.krad.uif.container.Group;
38 import org.kuali.rice.krad.uif.element.Action;
39 import org.kuali.rice.krad.uif.element.Label;
40 import org.kuali.rice.krad.uif.element.Message;
41 import org.kuali.rice.krad.uif.field.DataField;
42 import org.kuali.rice.krad.uif.field.Field;
43 import org.kuali.rice.krad.uif.field.FieldGroup;
44 import org.kuali.rice.krad.uif.field.InputField;
45 import org.kuali.rice.krad.uif.field.MessageField;
46 import org.kuali.rice.krad.uif.util.ColumnCalculationInfo;
47 import org.kuali.rice.krad.uif.util.ComponentFactory;
48 import org.kuali.rice.krad.uif.util.ComponentUtils;
49 import org.kuali.rice.krad.uif.util.ExpressionUtils;
50 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
51 import org.kuali.rice.krad.uif.view.View;
52 import org.kuali.rice.krad.uif.widget.Pager;
53 import org.kuali.rice.krad.uif.widget.RichTable;
54 import org.kuali.rice.krad.util.KRADUtils;
55 import org.kuali.rice.krad.web.form.UifFormBase;
56
57 import com.google.common.collect.Lists;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 @BeanTag(name = "tableCollectionLayout-bean", parent = "Uif-TableCollectionLayout")
73 public class TableLayoutManager extends GridLayoutManager implements CollectionLayoutManager {
74 private static final long serialVersionUID = 3622267585541524208L;
75
76 private boolean useShortLabels;
77 private boolean repeatHeader;
78 private Label headerLabelPrototype;
79
80 private boolean renderSequenceField;
81 private boolean generateAutoSequence;
82 private Field sequenceFieldPrototype;
83
84 private FieldGroup actionFieldPrototype;
85 private FieldGroup subCollectionFieldGroupPrototype;
86 private Field selectFieldPrototype;
87
88 private boolean separateAddLine;
89 private Group addLineGroup;
90
91
92 private int numberOfDataColumns;
93
94 private List<Label> headerLabels;
95 private List<Field> allRowFields;
96 private List<Field> firstRowFields;
97
98 private Pager pagerWidget;
99 private RichTable richTable;
100 private boolean headerAdded;
101
102 private int actionColumnIndex = -1;
103 private String actionColumnPlacement;
104
105
106 private Group rowDetailsGroup;
107 private boolean rowDetailsOpen;
108 private boolean showToggleAllDetails;
109 private Action toggleAllDetailsAction;
110 private boolean ajaxDetailsRetrieval;
111 private Action expandDetailsActionPrototype;
112
113
114 @KeepExpression
115 private String groupingTitle;
116 private String groupingPrefix;
117 private int groupingColumnIndex;
118 private List<String> groupingPropertyNames;
119
120
121 private boolean renderOnlyLeftTotalLabels;
122 private boolean showTotal;
123 private boolean showPageTotal;
124 private boolean showGroupTotal;
125 private boolean generateGroupTotalRows;
126 private Label totalLabel;
127 private Label pageTotalLabel;
128 private Label groupTotalLabelPrototype;
129
130 private List<String> columnsToCalculate;
131 private List<ColumnCalculationInfo> columnCalculations;
132 private List<Component> footerCalculationComponents;
133
134
135 private Map<String, String> conditionalRowCssClasses;
136
137 public TableLayoutManager() {
138 useShortLabels = false;
139 repeatHeader = false;
140 renderSequenceField = true;
141 generateAutoSequence = false;
142 separateAddLine = false;
143 rowDetailsOpen = false;
144
145 headerLabels = new ArrayList<Label>();
146 allRowFields = new ArrayList<Field>();
147 firstRowFields = new ArrayList<Field>();
148 columnsToCalculate = new ArrayList<String>();
149 columnCalculations = new ArrayList<ColumnCalculationInfo>();
150 conditionalRowCssClasses = new HashMap<String, String>();
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164 @Override
165 public void performInitialization(View view, Object model, Container container) {
166 CollectionGroup collectionGroup = (CollectionGroup) container;
167
168 this.setupDetails(collectionGroup, view);
169 this.setupGrouping(collectionGroup, view);
170
171 if (collectionGroup.isAddViaLightBox()) {
172 setSeparateAddLine(true);
173 }
174
175 super.performInitialization(view, model, container);
176
177 getRowCssClasses().clear();
178
179 if (generateAutoSequence && !(getSequenceFieldPrototype() instanceof MessageField)) {
180 sequenceFieldPrototype = ComponentFactory.getMessageField();
181 view.assignComponentIds(getSequenceFieldPrototype());
182 }
183 }
184
185
186
187
188
189
190
191
192
193
194 @Override
195 public void performApplyModel(View view, Object model, Container container) {
196 super.performApplyModel(view, model, container);
197
198 for (ColumnCalculationInfo cInfo : columnCalculations) {
199 ExpressionUtils.populatePropertyExpressionsFromGraph(cInfo, false);
200 }
201 }
202
203
204
205
206
207
208
209
210 @Override
211 public void performFinalize(View view, Object model, Container container) {
212 super.performFinalize(view, model, container);
213
214 UifFormBase formBase = (UifFormBase) model;
215
216 CollectionGroup collectionGroup = (CollectionGroup) container;
217
218 int totalColumns = getNumberOfDataColumns();
219 if (renderSequenceField) {
220 totalColumns++;
221 }
222
223 if (collectionGroup.isIncludeLineSelectionField()) {
224 totalColumns++;
225 }
226
227 if (collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly()) {
228 totalColumns++;
229 }
230
231 setNumberOfColumns(totalColumns);
232
233
234 if (UifConstants.ActionEvents.ADD_LINE.equals(formBase.getActionEvent())) {
235 String highlightScript = "jQuery(\"#" + container.getId() + " tr:first\").effect(\"highlight\",{}, 6000);";
236 String onReadyScript = collectionGroup.getOnDocumentReadyScript();
237 if (StringUtils.isNotBlank(onReadyScript)) {
238 highlightScript = onReadyScript + highlightScript;
239 }
240 collectionGroup.setOnDocumentReadyScript(highlightScript);
241 }
242
243
244 if (columnCalculations != null && richTable != null &&
245 this.getAllRowFields() != null && !this.getAllRowFields().isEmpty()) {
246 setupColumnCalculations(view, model, container, totalColumns);
247 }
248
249
250 if ((groupingPropertyNames != null || StringUtils.isNotBlank(this.getGroupingTitle())) && richTable != null) {
251 richTable.setGroupingOptionsJSString("{iGroupingColumnIndex: "
252 + groupingColumnIndex
253 + ", bGenerateGroupTotalRows:"
254 + this.generateGroupTotalRows
255 + ", bSetGroupingClassOnTR: true"
256 + ", sGroupingClass: 'uif-groupRow'"
257 + (this.getGroupingPrefix() != null ? ", sGroupLabelPrefix: '" + this.getGroupingPrefix() + "'" :
258 "")
259 + "}");
260 }
261
262
263 if ((this.getRichTable() == null || !this.getRichTable().isRender())
264 && ((CollectionGroup) container).isUseServerPaging()
265 && this.getPagerWidget() != null) {
266
267 CollectionLayoutUtils.setupPagerWidget(pagerWidget, collectionGroup, model);
268 }
269
270 }
271
272
273
274
275
276
277
278
279 private void setupGrouping(CollectionGroup collectionGroup, View view) {
280
281 String groupingTitleExpression = "";
282 if (StringUtils.isNotBlank(this.getPropertyExpression(UifPropertyPaths.GROUPING_TITLE))) {
283 groupingTitleExpression = this.getPropertyExpression(UifPropertyPaths.GROUPING_TITLE);
284 this.setGroupingTitle(this.getPropertyExpression(UifPropertyPaths.GROUPING_TITLE));
285 } else if (this.getGroupingPropertyNames() != null) {
286
287 for (String propertyName : this.getGroupingPropertyNames()) {
288 groupingTitleExpression = groupingTitleExpression + ", " + propertyName;
289 }
290
291 groupingTitleExpression = groupingTitleExpression.replaceFirst(", ",
292 "@{" + UifConstants.LINE_PATH_BIND_ADJUST_PREFIX);
293 groupingTitleExpression = groupingTitleExpression.replace(", ",
294 "}, @{" + UifConstants.LINE_PATH_BIND_ADJUST_PREFIX);
295 groupingTitleExpression = groupingTitleExpression.trim() + "}";
296 }
297
298 if (StringUtils.isNotBlank(groupingTitleExpression)) {
299 MessageField groupingMessageField = ComponentFactory.getColGroupingField();
300 groupingMessageField.getMessage().getPropertyExpressions().put(UifPropertyPaths.MESSAGE_TEXT,
301 groupingTitleExpression);
302
303 groupingMessageField.addDataAttribute(UifConstants.DataAttributes.ROLE,
304 UifConstants.RoleTypes.ROW_GROUPING);
305
306 view.assignComponentIds(groupingMessageField);
307
308 List<Component> theItems = new ArrayList<Component>();
309 theItems.add(groupingMessageField);
310 theItems.addAll(collectionGroup.getItems());
311 collectionGroup.setItems(theItems);
312 }
313 }
314
315
316
317
318
319
320
321
322
323 protected void setupColumnCalculations(View view, Object model, Container container, int totalColumns) {
324 footerCalculationComponents = new ArrayList<Component>(totalColumns);
325
326
327 for (int i = 0; i < totalColumns; i++) {
328 footerCalculationComponents.add(null);
329 }
330
331 int leftLabelColumnIndex = 0;
332 if (groupingPropertyNames != null || StringUtils.isNotBlank(this.getGroupingTitle())) {
333 leftLabelColumnIndex = 1;
334 }
335
336
337 for (ColumnCalculationInfo cInfo : columnCalculations) {
338
339 if (StringUtils.isNotBlank(cInfo.getPropertyName())) {
340 for (int i = 0; i < this.getNumberOfColumns(); i++) {
341 Component component = this.getAllRowFields().get(i);
342 if (component != null && component instanceof DataField &&
343 ((DataField) component).getPropertyName().equals(cInfo.getPropertyName())) {
344 cInfo.setColumnNumber(i);
345 }
346 }
347
348 this.getColumnsToCalculate().add(cInfo.getColumnNumber().toString());
349 } else {
350 throw new RuntimeException("TableLayoutManager(" + container.getId() + "->" + this.getId() +
351 ") ColumnCalculationInfo MUST have a propertyName set");
352 }
353
354
355 FieldGroup calculationFieldGroup = ComponentFactory.getFieldGroup();
356 calculationFieldGroup.addDataAttribute(UifConstants.DataAttributes.ROLE, "totalsBlock");
357
358 List<Component> calculationFieldGroupItems = new ArrayList<Component>();
359
360
361 if (cInfo.isShowPageTotal()) {
362 Field pageTotalDataField = setupTotalField(cInfo.getPageTotalField(), cInfo, this.isShowPageTotal(),
363 this.getPageTotalLabel(), "pageTotal", leftLabelColumnIndex);
364 calculationFieldGroupItems.add(pageTotalDataField);
365 }
366
367
368 if (cInfo.isShowTotal()) {
369 Field totalDataField = setupTotalField(cInfo.getTotalField(), cInfo, this.isShowTotal(),
370 this.getTotalLabel(), "total", leftLabelColumnIndex);
371
372 if (!cInfo.isRecalculateTotalClientSide()) {
373 totalDataField.addDataAttribute(UifConstants.DataAttributes.SKIP_TOTAL, "true");
374 }
375
376 calculationFieldGroupItems.add(totalDataField);
377 }
378
379
380
381 if (cInfo.isShowGroupTotal()) {
382 Field groupTotalDataField = setupTotalField(cInfo.getGroupTotalFieldPrototype(), cInfo,
383 this.isShowGroupTotal(), this.getGroupTotalLabelPrototype(), "groupTotal",
384 leftLabelColumnIndex);
385 groupTotalDataField.setId(container.getId() + "_gTotal" + cInfo.getColumnNumber());
386 groupTotalDataField.setStyle("display: none;");
387
388 calculationFieldGroupItems.add(groupTotalDataField);
389
390 if (this.isRenderOnlyLeftTotalLabels() && !this.isShowGroupTotal()) {
391 generateGroupTotalRows = false;
392 } else {
393 generateGroupTotalRows = true;
394 }
395 }
396
397 calculationFieldGroup.setItems(calculationFieldGroupItems);
398
399 view.assignComponentIds(calculationFieldGroup);
400
401
402
403
404 Component component = footerCalculationComponents.get(cInfo.getColumnNumber());
405 if (component != null && component instanceof FieldGroup) {
406 Group verticalComboCalcGroup = ComponentFactory.getVerticalBoxGroup();
407 view.assignComponentIds(verticalComboCalcGroup);
408
409 List<Component> comboGroupItems = new ArrayList<Component>();
410 comboGroupItems.add(component);
411 comboGroupItems.add(calculationFieldGroup);
412 verticalComboCalcGroup.setItems(comboGroupItems);
413
414 footerCalculationComponents.set(cInfo.getColumnNumber(), verticalComboCalcGroup);
415 } else if (component != null && component instanceof Group) {
416 List<Component> comboGroupItems = new ArrayList<Component>();
417 comboGroupItems.addAll(((Group) component).getItems());
418 comboGroupItems.add(calculationFieldGroup);
419
420 ((Group) component).setItems(comboGroupItems);
421
422 footerCalculationComponents.set(cInfo.getColumnNumber(), component);
423 } else {
424 footerCalculationComponents.set(cInfo.getColumnNumber(), calculationFieldGroup);
425 }
426 }
427
428
429
430 if (this.renderOnlyLeftTotalLabels && footerCalculationComponents.get(leftLabelColumnIndex) == null) {
431 Group labelGroup = ComponentFactory.getVerticalBoxGroup();
432 view.assignComponentIds(labelGroup);
433 List<Component> groupItems = new ArrayList<Component>();
434
435 if (this.isShowGroupTotal()) {
436
437 groupTotalLabelPrototype.setStyle("display: none;");
438 groupTotalLabelPrototype.addDataAttribute(UifConstants.DataAttributes.ROLE, "groupTotalLabel");
439 view.assignComponentIds(groupTotalLabelPrototype);
440 groupItems.add(groupTotalLabelPrototype);
441 }
442
443 if (this.isShowPageTotal()) {
444 view.assignComponentIds(pageTotalLabel);
445 pageTotalLabel.addDataAttribute(UifConstants.DataAttributes.ROLE, "pageTotal");
446 groupItems.add(pageTotalLabel);
447 }
448
449 if (this.isShowTotal()) {
450 view.assignComponentIds(totalLabel);
451 groupItems.add(totalLabel);
452 }
453
454 labelGroup.setItems(groupItems);
455
456 footerCalculationComponents.set(leftLabelColumnIndex, labelGroup);
457 }
458
459
460
461 for (Component component : footerCalculationComponents) {
462 view.getViewHelperService().spawnSubLifecyle(view, model, component, container, null, null);
463 }
464 }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480 protected Field setupTotalField(Field totalField, ColumnCalculationInfo cInfo, boolean show, Label leftLabel,
481 String type, int leftLabelColumnIndex) {
482
483 Field totalDataField = totalField;
484 totalDataField.addDataAttribute(UifConstants.DataAttributes.ROLE, type);
485 totalDataField.addDataAttribute("function", cInfo.getCalculationFunctionName());
486 totalDataField.addDataAttribute("params", cInfo.getCalculationFunctionExtraData());
487
488 if (cInfo.getColumnNumber() != leftLabelColumnIndex) {
489
490
491 totalDataField.getFieldLabel().setRender(!this.isRenderOnlyLeftTotalLabels());
492 } else if (cInfo.getColumnNumber() == leftLabelColumnIndex && this.isRenderOnlyLeftTotalLabels()) {
493
494
495 totalDataField.setFieldLabel(leftLabel);
496 }
497
498 if (this.isRenderOnlyLeftTotalLabels()) {
499 totalDataField.setRender(show);
500 }
501
502 return totalDataField;
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516 public void buildLine(View view, Object model, CollectionGroup collectionGroup, List<Field> lineFields,
517 List<FieldGroup> subCollectionFields, String bindingPath, List<Action> actions, String idSuffix,
518 Object currentLine, int lineIndex) {
519
520
521
522 ExpressionEvaluator expressionEvaluator = view.getViewHelperService().getExpressionEvaluator();
523 for (Field lineField : lineFields) {
524 lineField.pushObjectToContext(UifConstants.ContextVariableNames.PARENT, collectionGroup);
525 lineField.pushAllToContext(view.getViewHelperService().getCommonContext(view, lineField));
526
527 expressionEvaluator.evaluatePropertyExpression(view, lineField.getContext(), lineField,
528 UifPropertyPaths.ROW_SPAN, true);
529 expressionEvaluator.evaluatePropertyExpression(view, lineField.getContext(), lineField,
530 UifPropertyPaths.COL_SPAN, true);
531 expressionEvaluator.evaluatePropertyExpression(view, lineField.getContext(), lineField,
532 UifPropertyPaths.REQUIRED, true);
533 expressionEvaluator.evaluatePropertyExpression(view, lineField.getContext(), lineField,
534 UifPropertyPaths.READ_ONLY, true);
535 }
536
537
538 if (allRowFields.isEmpty()) {
539 if (isSuppressLineWrapping()) {
540 setNumberOfDataColumns(lineFields.size());
541 } else {
542 setNumberOfDataColumns(getNumberOfColumns());
543 }
544 }
545
546 boolean isAddLine = false;
547
548
549 if (lineIndex == -1 || (lineFields.size() != numberOfDataColumns
550 && ((lineIndex + 1) * numberOfDataColumns) < lineFields.size())) {
551 isAddLine = true;
552 }
553
554
555 if (lineIndex == 0 || this.firstRowFields.isEmpty()) {
556 this.firstRowFields = lineFields;
557 }
558
559 boolean renderActions = collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly();
560 int extraColumns = 0;
561 String rowCss = "";
562 boolean addLineInTable =
563 collectionGroup.isRenderAddLine() && !collectionGroup.isReadOnly() && !isSeparateAddLine();
564
565 if (collectionGroup.isHighlightNewItems() && ((UifFormBase) model).isAddedCollectionItem(currentLine)) {
566 rowCss = collectionGroup.getNewItemsCssClass();
567 } else if (isAddLine && addLineInTable) {
568 rowCss = collectionGroup.getAddItemCssClass();
569 this.addStyleClass(CssConstants.Classes.HAS_ADD_LINE);
570 }
571
572
573 if (rowCss == null) {
574 rowCss = "";
575 }
576
577
578 if (conditionalRowCssClasses != null && !conditionalRowCssClasses.isEmpty()) {
579 int oddRemainder = 1;
580 if (!addLineInTable) {
581 oddRemainder = 0;
582 }
583
584 boolean isOdd = lineIndex % 2 == oddRemainder || lineIndex == -1;
585 Map<String, Object> lineContext = new HashMap<String, Object>();
586
587 lineContext.putAll(this.getContext());
588 lineContext.put(UifConstants.ContextVariableNames.LINE, currentLine);
589 lineContext.put(UifConstants.ContextVariableNames.MANAGER, this);
590 lineContext.put(UifConstants.ContextVariableNames.VIEW, view);
591 lineContext.put(UifConstants.ContextVariableNames.LINE_SUFFIX, idSuffix);
592 lineContext.put(UifConstants.ContextVariableNames.INDEX, Integer.valueOf(lineIndex));
593 lineContext.put(UifConstants.ContextVariableNames.COLLECTION_GROUP, collectionGroup);
594 lineContext.put(UifConstants.ContextVariableNames.IS_ADD_LINE, isAddLine && !isSeparateAddLine());
595 lineContext.put(UifConstants.ContextVariableNames.READONLY_LINE, collectionGroup.isReadOnly());
596
597
598 rowCss = rowCss + " " + KRADUtils.generateRowCssClassString(conditionalRowCssClasses, lineIndex, isOdd,
599 lineContext, expressionEvaluator);
600 }
601
602 rowCss = StringUtils.removeStart(rowCss, " ");
603 this.getRowCssClasses().add(rowCss);
604
605
606 if (isAddLine && separateAddLine) {
607 if (StringUtils.isBlank(addLineGroup.getTitle()) && StringUtils.isBlank(
608 addLineGroup.getHeader().getHeaderText())) {
609 addLineGroup.getHeader().setHeaderText(collectionGroup.getAddLabel());
610 }
611 addLineGroup.setItems(lineFields);
612
613 List<Component> footerItems = new ArrayList<Component>(actions);
614 footerItems.addAll(addLineGroup.getFooter().getItems());
615 addLineGroup.getFooter().setItems(footerItems);
616
617 if (collectionGroup.isAddViaLightBox()) {
618 String actionScript = "showLightboxComponent('" + addLineGroup.getId() + "');";
619 if (StringUtils.isNotBlank(collectionGroup.getAddViaLightBoxAction().getActionScript())) {
620 actionScript = collectionGroup.getAddViaLightBoxAction().getActionScript() + actionScript;
621 }
622 collectionGroup.getAddViaLightBoxAction().setActionScript(actionScript);
623 addLineGroup.setStyle("display: none");
624 }
625
626 return;
627 }
628
629
630 if (!headerAdded) {
631 headerLabels = new ArrayList<Label>();
632 allRowFields = new ArrayList<Field>();
633
634 buildTableHeaderRows(collectionGroup, lineFields);
635 ComponentUtils.pushObjectToContext(headerLabels, UifConstants.ContextVariableNames.LINE, currentLine);
636 ComponentUtils.pushObjectToContext(headerLabels, UifConstants.ContextVariableNames.INDEX, new Integer(
637 lineIndex));
638 headerAdded = true;
639 }
640
641
642 for (Field field : lineFields) {
643 field.setLabelRendered(true);
644 field.setFieldLabel(null);
645
646 setCellAttributes(field);
647 }
648
649 int rowCount = calculateNumberOfRows(lineFields);
650 int rowSpan = rowCount + subCollectionFields.size();
651
652 if (actionColumnIndex == 1 && renderActions) {
653 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
654 }
655
656
657 if (renderSequenceField) {
658 Field sequenceField = null;
659 if (!isAddLine) {
660 sequenceField = ComponentUtils.copy(getSequenceFieldPrototype(), idSuffix);
661
662
663 sequenceField.addDataAttribute(UifConstants.DataAttributes.VIGNORE, "yes");
664
665 if (generateAutoSequence && (sequenceField instanceof MessageField)) {
666 ((MessageField) sequenceField).setMessageText(Integer.toString(lineIndex + 1));
667 }
668 } else {
669 sequenceField = ComponentFactory.getMessageField();
670 view.assignComponentIds(sequenceField);
671
672 Message sequenceMessage = ComponentUtils.copy(collectionGroup.getAddLineLabel(), idSuffix);
673 ((MessageField) sequenceField).setMessage(sequenceMessage);
674
675
676 sequenceField.setCellWidth(getSequenceFieldPrototype().getCellWidth());
677 sequenceField.setCellStyle(getSequenceFieldPrototype().getCellStyle());
678 }
679
680 sequenceField.setRowSpan(rowSpan);
681
682 if (sequenceField instanceof DataBinding) {
683 ((DataBinding) sequenceField).getBindingInfo().setBindByNamePrefix(bindingPath);
684 }
685
686 setCellAttributes(sequenceField);
687
688 ComponentUtils.updateContextForLine(sequenceField, currentLine, lineIndex, idSuffix);
689 allRowFields.add(sequenceField);
690 extraColumns++;
691
692 if (actionColumnIndex == 2 && renderActions) {
693 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
694 }
695 }
696
697
698 if (collectionGroup.isIncludeLineSelectionField()) {
699 Field selectField = ComponentUtils.copy(getSelectFieldPrototype(), idSuffix);
700 CollectionLayoutUtils.prepareSelectFieldForLine(selectField, collectionGroup, bindingPath, currentLine);
701
702 ComponentUtils.updateContextForLine(selectField, currentLine, lineIndex, idSuffix);
703 setCellAttributes(selectField);
704
705 allRowFields.add(selectField);
706
707 extraColumns++;
708
709 if (renderActions) {
710 if ((actionColumnIndex == 3 && renderSequenceField) || (actionColumnIndex == 2
711 && !renderSequenceField)) {
712 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
713 }
714 }
715 }
716
717
718 int cellPosition = 0;
719
720 boolean renderActionsLast = actionColumnIndex == -1 || actionColumnIndex > lineFields.size() + extraColumns;
721 boolean hasGrouping = (groupingPropertyNames != null || StringUtils.isNotBlank(this.getGroupingTitle()));
722 boolean insertActionField = false;
723
724 for (Field lineField : lineFields) {
725
726
727
728
729
730 insertActionField = (cellPosition != 0 && lineFields.size() != numberOfDataColumns)
731 && renderActions
732 && renderActionsLast
733 && ((cellPosition % numberOfDataColumns) == 0);
734
735 cellPosition += lineField.getColSpan();
736
737
738 Map<String, String> lineFieldDataAttributes = lineField.getDataAttributes();
739 if (hasGrouping
740 && (lineField instanceof MessageField)
741 &&
742 lineFieldDataAttributes != null
743 && UifConstants.RoleTypes.ROW_GROUPING.equals(lineFieldDataAttributes
744 .get(UifConstants.DataAttributes.ROLE))) {
745 int groupFieldIndex = allRowFields.size() - extraColumns;
746 allRowFields.add(groupFieldIndex, lineField);
747 groupingColumnIndex = 0;
748 if (isAddLine) {
749 ((MessageField) lineField).getMessage().getPropertyExpressions().remove(
750 UifPropertyPaths.MESSAGE_TEXT);
751 ((MessageField) lineField).getMessage().setMessageText("addLine");
752 }
753 } else {
754
755 if (insertActionField) {
756 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
757 }
758
759 allRowFields.add(lineField);
760 }
761
762
763 if (!renderActionsLast && cellPosition == (actionColumnIndex - extraColumns - 1)) {
764 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
765 }
766
767
768 if (lineField instanceof FieldGroup && ((FieldGroup) lineField).getItems() != null) {
769 for (Component component : ((FieldGroup) lineField).getItems()) {
770 if (component != null
771 && component instanceof Action
772 && (component.getDataAttributes() != null)
773 && component.getDataAttributes().get("role") != null
774 && component.getDataAttributes().get("role").equals("detailsLink")
775 && StringUtils.isBlank(((Action) component).getActionScript())) {
776 ((Action) component).setActionScript("rowDetailsActionHandler(this,'" + this.getId() + "');");
777 }
778 }
779 }
780
781
782
783 if (lineField instanceof InputField && columnCalculations != null) {
784 for (ColumnCalculationInfo cInfo : columnCalculations) {
785 if (cInfo.getPropertyName().equals(((InputField) lineField).getPropertyName())) {
786 if (cInfo.isCalculateOnKeyUp()) {
787 lineField.addDataAttribute(UifConstants.DataAttributes.TOTAL, "keyup");
788 } else {
789 lineField.addDataAttribute(UifConstants.DataAttributes.TOTAL, "change");
790 }
791 lineField.addStyleClass("uif-calculationField");
792 }
793 }
794 }
795 }
796
797 if (lineFields.size() == numberOfDataColumns && renderActions && renderActionsLast) {
798 addActionColumn(idSuffix, currentLine, lineIndex, rowSpan, actions);
799 }
800
801
802 for (FieldGroup subCollectionField : subCollectionFields) {
803 subCollectionField.setColSpan(numberOfDataColumns);
804 }
805
806
807 allRowFields.addAll(subCollectionFields);
808 }
809
810
811
812
813
814
815
816
817
818
819 private void addActionColumn(String idSuffix, Object currentLine, int lineIndex, int rowSpan,
820 List<Action> actions) {
821 FieldGroup lineActionsField = ComponentUtils.copy(getActionFieldPrototype(), idSuffix);
822
823 ComponentUtils.updateContextForLine(lineActionsField, currentLine, lineIndex, idSuffix);
824 lineActionsField.setRowSpan(rowSpan);
825 lineActionsField.setItems(actions);
826
827 setCellAttributes(lineActionsField);
828
829 allRowFields.add(lineActionsField);
830 }
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849 protected void buildTableHeaderRows(CollectionGroup collectionGroup, List<Field> lineFields) {
850
851
852 int rowCount = calculateNumberOfRows(lineFields);
853
854 boolean renderActions = collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly();
855
856 String idSuffix = collectionGroup.getSubCollectionSuffix();
857
858 int extraColumns = 0;
859
860 if (actionColumnIndex == 1 && renderActions) {
861 addActionHeader(rowCount, idSuffix, 1);
862 }
863
864
865 if (renderSequenceField) {
866 getSequenceFieldPrototype().setLabelRendered(true);
867 getSequenceFieldPrototype().setRowSpan(rowCount);
868 addHeaderField(getSequenceFieldPrototype(), idSuffix, 1);
869 extraColumns++;
870
871 if (actionColumnIndex == 2 && renderActions) {
872 addActionHeader(rowCount, idSuffix, 2);
873 }
874 }
875
876
877 if (collectionGroup.isIncludeLineSelectionField()) {
878 getSelectFieldPrototype().setLabelRendered(true);
879 getSelectFieldPrototype().setRowSpan(rowCount);
880 addHeaderField(getSelectFieldPrototype(), idSuffix, 1);
881 extraColumns++;
882
883 if (actionColumnIndex == 3 && renderActions && renderSequenceField) {
884 addActionHeader(rowCount, idSuffix, 3);
885 } else if (actionColumnIndex == 2 && renderActions) {
886 addActionHeader(rowCount, idSuffix, 2);
887 }
888 }
889
890
891 int cellPosition = 0;
892 boolean renderActionsLast = actionColumnIndex == -1 || actionColumnIndex > lineFields.size() + extraColumns;
893 boolean insertActionHeader = false;
894 for (Field field : lineFields) {
895 if (!field.isRender() && StringUtils.isEmpty(field.getProgressiveRender())) {
896 continue;
897 }
898
899
900
901
902
903
904 insertActionHeader = (cellPosition != 0
905 && lineFields.size() != numberOfDataColumns
906 && renderActions
907 && renderActionsLast
908 && ((cellPosition % numberOfDataColumns) == 0));
909
910 if (insertActionHeader) {
911 addActionHeader(rowCount, idSuffix, cellPosition);
912 }
913
914 cellPosition += field.getColSpan();
915 addHeaderField(field, idSuffix, cellPosition);
916
917
918 if (renderActions && !renderActionsLast && cellPosition == actionColumnIndex - extraColumns - 1) {
919 cellPosition += 1;
920 addActionHeader(rowCount, idSuffix, cellPosition);
921 }
922 }
923
924 if (lineFields.size() == numberOfDataColumns && renderActions && renderActionsLast) {
925 cellPosition += 1;
926 addActionHeader(rowCount, idSuffix, cellPosition);
927 }
928 }
929
930
931
932
933
934
935
936
937 protected void addActionHeader(int rowCount, String idSuffix, int cellPosition) {
938 getActionFieldPrototype().setLabelRendered(true);
939 getActionFieldPrototype().setRowSpan(rowCount);
940 addHeaderField(getActionFieldPrototype(), idSuffix, cellPosition);
941 }
942
943
944
945
946
947
948
949
950
951
952 protected void addHeaderField(Field field, String idSuffix, int column) {
953 String labelSuffix = UifConstants.IdSuffixes.COLUMN + column;
954 if (StringUtils.isNotBlank(idSuffix)) {
955 labelSuffix = idSuffix + labelSuffix;
956 }
957
958 Label headerLabel = ComponentUtils.copy(getHeaderLabelPrototype(), labelSuffix);
959
960 if (useShortLabels) {
961 headerLabel.setLabelText(field.getShortLabel());
962 } else {
963 headerLabel.setLabelText(field.getLabel());
964 }
965
966 headerLabel.setRowSpan(field.getRowSpan());
967 headerLabel.setColSpan(field.getColSpan());
968
969 if ((field.getRequired() != null) && field.getRequired().booleanValue()) {
970 headerLabel.getRequiredMessage().setRender(!field.isReadOnly());
971 } else {
972 headerLabel.getRequiredMessage().setRender(false);
973 }
974
975 setCellAttributes(field);
976
977
978 headerLabel.setCellCssClasses(field.getCellCssClasses());
979 headerLabel.setCellStyle(field.getCellStyle());
980 headerLabel.setCellWidth(field.getCellWidth());
981
982 headerLabels.add(headerLabel);
983 }
984
985
986
987
988
989
990
991
992
993 protected int calculateNumberOfRows(List<? extends Field> items) {
994 int rowCount = 0;
995
996
997 if (isSuppressLineWrapping()) {
998 return 1;
999 }
1000
1001
1002 if (items.size() % getNumberOfDataColumns() > 0) {
1003
1004 Field field = items.get(items.size() - 1);
1005
1006 int colSize = 0;
1007 for (Field f : items) {
1008 colSize += f.getColSpan();
1009 }
1010
1011 field.setColSpan(1 + (numberOfDataColumns - (colSize % numberOfDataColumns)));
1012 rowCount = ((items.size() / getNumberOfDataColumns()) + 1);
1013 } else {
1014 rowCount = items.size() / getNumberOfDataColumns();
1015 }
1016 return rowCount;
1017 }
1018
1019
1020
1021
1022 @Override
1023 public Class<? extends Container> getSupportedContainer() {
1024 return CollectionGroup.class;
1025 }
1026
1027
1028
1029
1030 @Override
1031 public List<Component> getComponentsForLifecycle() {
1032 List<Component> components = super.getComponentsForLifecycle();
1033
1034 components.add(pagerWidget);
1035 components.add(richTable);
1036 components.add(addLineGroup);
1037 components.addAll(headerLabels);
1038 components.addAll(allRowFields);
1039
1040 if (columnCalculations != null) {
1041 for (ColumnCalculationInfo cInfo : columnCalculations) {
1042 components.add(cInfo.getTotalField());
1043 components.add(cInfo.getPageTotalField());
1044 components.add(cInfo.getGroupTotalFieldPrototype());
1045 }
1046 }
1047
1048 if (isShowToggleAllDetails()) {
1049 components.add(toggleAllDetailsAction);
1050 }
1051
1052 return components;
1053 }
1054
1055
1056
1057
1058 @Override
1059 public List<Component> getComponentPrototypes() {
1060 List<Component> components = super.getComponentPrototypes();
1061
1062 components.add(getHeaderLabelPrototype());
1063 components.add(getSequenceFieldPrototype());
1064 components.add(getActionFieldPrototype());
1065 components.add(getSubCollectionFieldGroupPrototype());
1066 components.add(getSelectFieldPrototype());
1067
1068 return components;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077 @BeanTagAttribute(name = "useShortLabels")
1078 public boolean isUseShortLabels() {
1079 return this.useShortLabels;
1080 }
1081
1082
1083
1084
1085
1086
1087 public void setUseShortLabels(boolean useShortLabels) {
1088 this.useShortLabels = useShortLabels;
1089 }
1090
1091
1092
1093
1094
1095
1096
1097 @BeanTagAttribute(name = "repeatHeader")
1098 public boolean isRepeatHeader() {
1099 return this.repeatHeader;
1100 }
1101
1102
1103
1104
1105
1106
1107 public void setRepeatHeader(boolean repeatHeader) {
1108 this.repeatHeader = repeatHeader;
1109 }
1110
1111
1112
1113
1114
1115
1116
1117 @BeanTagAttribute(name = "headerLabelPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1118 public Label getHeaderLabelPrototype() {
1119 return this.headerLabelPrototype;
1120 }
1121
1122
1123
1124
1125
1126
1127 public void setHeaderLabelPrototype(Label headerLabelPrototype) {
1128 this.headerLabelPrototype = headerLabelPrototype;
1129 }
1130
1131
1132
1133
1134
1135
1136 public List<Label> getHeaderLabels() {
1137 return this.headerLabels;
1138 }
1139
1140
1141
1142
1143
1144
1145 @BeanTagAttribute(name = "renderSequenceField")
1146 public boolean isRenderSequenceField() {
1147 return this.renderSequenceField;
1148 }
1149
1150
1151
1152
1153
1154
1155 public void setRenderSequenceField(boolean renderSequenceField) {
1156 this.renderSequenceField = renderSequenceField;
1157 }
1158
1159
1160
1161
1162
1163
1164
1165 @BeanTagAttribute(name = "sequencePropertyName")
1166 public String getSequencePropertyName() {
1167 if ((getSequenceFieldPrototype() != null) && (getSequenceFieldPrototype() instanceof DataField)) {
1168 return ((DataField) getSequenceFieldPrototype()).getPropertyName();
1169 }
1170
1171 return null;
1172 }
1173
1174
1175
1176
1177
1178
1179 public void setSequencePropertyName(String sequencePropertyName) {
1180 if ((getSequenceFieldPrototype() != null) && (getSequenceFieldPrototype() instanceof DataField)) {
1181 ((DataField) getSequenceFieldPrototype()).setPropertyName(sequencePropertyName);
1182 }
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195 @BeanTagAttribute(name = "generateAutoSequence")
1196 public boolean isGenerateAutoSequence() {
1197 return this.generateAutoSequence;
1198 }
1199
1200
1201
1202
1203
1204
1205 public void setGenerateAutoSequence(boolean generateAutoSequence) {
1206 this.generateAutoSequence = generateAutoSequence;
1207 }
1208
1209
1210
1211
1212
1213
1214
1215 @BeanTagAttribute(name = "sequenceFieldPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1216 public Field getSequenceFieldPrototype() {
1217 return this.sequenceFieldPrototype;
1218 }
1219
1220
1221
1222
1223
1224
1225 public void setSequenceFieldPrototype(Field sequenceFieldPrototype) {
1226 this.sequenceFieldPrototype = sequenceFieldPrototype;
1227 }
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239 @BeanTagAttribute(name = "actionFieldPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1240 public FieldGroup getActionFieldPrototype() {
1241 return this.actionFieldPrototype;
1242 }
1243
1244
1245
1246
1247
1248
1249 public void setActionFieldPrototype(FieldGroup actionFieldPrototype) {
1250 this.actionFieldPrototype = actionFieldPrototype;
1251 }
1252
1253
1254
1255
1256 @BeanTagAttribute(name = "subCollectionFieldGroupPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1257 public FieldGroup getSubCollectionFieldGroupPrototype() {
1258 return this.subCollectionFieldGroupPrototype;
1259 }
1260
1261
1262
1263
1264
1265
1266 public void setSubCollectionFieldGroupPrototype(FieldGroup subCollectionFieldGroupPrototype) {
1267 this.subCollectionFieldGroupPrototype = subCollectionFieldGroupPrototype;
1268 }
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 @BeanTagAttribute(name = "selectFieldPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1287 public Field getSelectFieldPrototype() {
1288 return selectFieldPrototype;
1289 }
1290
1291
1292
1293
1294
1295
1296 public void setSelectFieldPrototype(Field selectFieldPrototype) {
1297 this.selectFieldPrototype = selectFieldPrototype;
1298 }
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 @BeanTagAttribute(name = "separateAddLine")
1315 public boolean isSeparateAddLine() {
1316 return separateAddLine;
1317 }
1318
1319
1320
1321
1322
1323
1324 public void setSeparateAddLine(boolean separateAddLine) {
1325 this.separateAddLine = separateAddLine;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 @BeanTagAttribute(name = "addLineGroup", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1343 public Group getAddLineGroup() {
1344 return addLineGroup;
1345 }
1346
1347
1348
1349
1350
1351
1352 public void setAddLineGroup(Group addLineGroup) {
1353 this.addLineGroup = addLineGroup;
1354 }
1355
1356
1357
1358
1359
1360
1361 public List<Field> getAllRowFields() {
1362 return this.allRowFields;
1363 }
1364
1365
1366
1367
1368
1369
1370 public List<Field> getFirstRowFields() {
1371 return firstRowFields;
1372 }
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386 public Pager getPagerWidget() {
1387 return pagerWidget;
1388 }
1389
1390
1391
1392
1393
1394
1395 public void setPagerWidget(Pager pagerWidget) {
1396 this.pagerWidget = pagerWidget;
1397 }
1398
1399
1400
1401
1402
1403
1404 @BeanTagAttribute(name = "richTable", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1405 public RichTable getRichTable() {
1406 return this.richTable;
1407 }
1408
1409
1410
1411
1412
1413
1414 public void setRichTable(RichTable richTable) {
1415 this.richTable = richTable;
1416 }
1417
1418
1419
1420
1421 @BeanTagAttribute(name = "numberOfDataColumns")
1422 public int getNumberOfDataColumns() {
1423 return this.numberOfDataColumns;
1424 }
1425
1426
1427
1428
1429 public void setNumberOfDataColumns(int numberOfDataColumns) {
1430 this.numberOfDataColumns = numberOfDataColumns;
1431 }
1432
1433
1434
1435
1436 @BeanTagAttribute(name = "hiddenColumns", type = BeanTagAttribute.AttributeType.SETVALUE)
1437 public Set<String> getHiddenColumns() {
1438 if (richTable != null) {
1439 return richTable.getHiddenColumns();
1440 }
1441
1442 return null;
1443 }
1444
1445
1446
1447
1448
1449
1450 public void setHiddenColumns(Set<String> hiddenColumns) {
1451 if (richTable != null) {
1452 richTable.setHiddenColumns(hiddenColumns);
1453 }
1454 }
1455
1456
1457
1458
1459 @BeanTagAttribute(name = "sortableColumns", type = BeanTagAttribute.AttributeType.SETVALUE)
1460 public Set<String> getSortableColumns() {
1461 if (richTable != null) {
1462 return richTable.getSortableColumns();
1463 }
1464
1465 return null;
1466 }
1467
1468
1469
1470
1471
1472
1473 public void setSortableColumns(Set<String> sortableColumns) {
1474 if (richTable != null) {
1475 richTable.setSortableColumns(sortableColumns);
1476 }
1477 }
1478
1479
1480
1481
1482
1483
1484 @BeanTagAttribute(name = "actionColumnIndex")
1485 public int getActionColumnIndex() {
1486 return actionColumnIndex;
1487 }
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500 @BeanTagAttribute(name = "actionColumnPlacement")
1501 public String getActionColumnPlacement() {
1502 return actionColumnPlacement;
1503 }
1504
1505
1506
1507
1508
1509
1510 public void setActionColumnPlacement(String actionColumnPlacement) {
1511 this.actionColumnPlacement = actionColumnPlacement;
1512
1513 if ("LEFT".equals(actionColumnPlacement)) {
1514 actionColumnIndex = 1;
1515 } else if ("RIGHT".equals(actionColumnPlacement)) {
1516 actionColumnIndex = -1;
1517 } else if (StringUtils.isNumeric(actionColumnPlacement)) {
1518 actionColumnIndex = Integer.parseInt(actionColumnPlacement);
1519 }
1520 }
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537 @BeanTagAttribute(name = "rowDetailsGroup", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1538 public Group getRowDetailsGroup() {
1539 return rowDetailsGroup;
1540 }
1541
1542
1543
1544
1545
1546
1547 public void setRowDetailsGroup(Group rowDetailsGroup) {
1548 this.rowDetailsGroup = rowDetailsGroup;
1549 }
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559 public void setupDetails(CollectionGroup collectionGroup, View view) {
1560 if (getRowDetailsGroup() == null || this.getRichTable() == null || !this.getRichTable().isRender()) {
1561 return;
1562 }
1563
1564
1565 collectionGroup.addDataAttribute(UifConstants.DataAttributes.DETAILS_DEFAULT_OPEN, Boolean.toString(
1566 this.rowDetailsOpen));
1567
1568 toggleAllDetailsAction.addDataAttribute("open", Boolean.toString(this.rowDetailsOpen));
1569 toggleAllDetailsAction.addDataAttribute("tableid", this.getId());
1570
1571 this.getRowDetailsGroup().setHidden(true);
1572
1573 FieldGroup detailsFieldGroup = ComponentFactory.getFieldGroup();
1574
1575 TreeMap<String, String> dataAttributes = new TreeMap<String, String>();
1576 dataAttributes.put(UifConstants.DataAttributes.ROLE, "detailsFieldGroup");
1577 detailsFieldGroup.setDataAttributes(dataAttributes);
1578
1579 Action rowDetailsAction = this.getExpandDetailsActionPrototype();
1580 rowDetailsAction.addDataAttribute(UifConstants.DataAttributes.ROLE, "detailsLink");
1581 rowDetailsAction.setId(collectionGroup.getId() + UifConstants.IdSuffixes.DETAIL_LINK);
1582
1583 List<Component> detailsItems = new ArrayList<Component>();
1584 detailsItems.add(rowDetailsAction);
1585
1586 dataAttributes = new TreeMap<String, String>();
1587 dataAttributes.put("role", "details");
1588 dataAttributes.put("open", Boolean.toString(this.rowDetailsOpen));
1589 this.getRowDetailsGroup().setDataAttributes(dataAttributes);
1590
1591 if (ajaxDetailsRetrieval) {
1592 this.getRowDetailsGroup().setRender(false);
1593 this.getRowDetailsGroup().setDisclosedByAction(true);
1594 }
1595
1596 detailsItems.add(getRowDetailsGroup());
1597 detailsFieldGroup.setItems(detailsItems);
1598 detailsFieldGroup.setId(collectionGroup.getId() + UifConstants.IdSuffixes.DETAIL_GROUP);
1599 view.assignComponentIds(detailsFieldGroup);
1600
1601 List<Component> theItems = new ArrayList<Component>();
1602 theItems.add(detailsFieldGroup);
1603 theItems.addAll(collectionGroup.getItems());
1604
1605 collectionGroup.setItems(theItems);
1606 }
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 public List<String> getColumnsToCalculate() {
1619 return columnsToCalculate;
1620 }
1621
1622
1623
1624
1625
1626
1627
1628
1629 public void completeValidation(ValidationTrace tracer) {
1630 tracer.addBean("TableLayoutManager", getId());
1631
1632 if (getRowDetailsGroup() != null) {
1633 boolean validTable = false;
1634 if (getRichTable() != null) {
1635 if (getRichTable().isRender()) {
1636 validTable = true;
1637 }
1638 }
1639 if (!validTable) {
1640 String currentValues[] = {"rowDetailsGroup =" + getRowDetailsGroup(), "richTable =" + getRichTable()};
1641 tracer.createError("If rowDetailsGroup is set richTable must be set and its render true",
1642 currentValues);
1643 }
1644
1645 }
1646 }
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656 @BeanTagAttribute(name = "showTotal")
1657 public boolean isShowTotal() {
1658 return showTotal;
1659 }
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670 public void setShowTotal(boolean showTotal) {
1671 this.showTotal = showTotal;
1672 }
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683 @BeanTagAttribute(name = "showPageTotal")
1684 public boolean isShowPageTotal() {
1685 return showPageTotal;
1686 }
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697 public void setShowPageTotal(boolean showPageTotal) {
1698 this.showPageTotal = showPageTotal;
1699 }
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710 @BeanTagAttribute(name = "showGroupTotal")
1711 public boolean isShowGroupTotal() {
1712 return showGroupTotal;
1713 }
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724 public void setShowGroupTotal(boolean showGroupTotal) {
1725 this.showGroupTotal = showGroupTotal;
1726 }
1727
1728
1729
1730
1731
1732
1733
1734 @BeanTagAttribute(name = "totalLabel", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1735 public Label getTotalLabel() {
1736 return totalLabel;
1737 }
1738
1739
1740
1741
1742
1743
1744 public void setTotalLabel(Label totalLabel) {
1745 this.totalLabel = totalLabel;
1746 }
1747
1748
1749
1750
1751
1752
1753
1754 @BeanTagAttribute(name = "pageTotalLabel", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1755 public Label getPageTotalLabel() {
1756 return pageTotalLabel;
1757 }
1758
1759
1760
1761
1762
1763
1764 public void setPageTotalLabel(Label pageTotalLabel) {
1765 this.pageTotalLabel = pageTotalLabel;
1766 }
1767
1768
1769
1770
1771
1772
1773
1774 @BeanTagAttribute(name = "groupTotalLabelPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1775 public Label getGroupTotalLabelPrototype() {
1776 return groupTotalLabelPrototype;
1777 }
1778
1779
1780
1781
1782
1783
1784 public void setGroupTotalLabelPrototype(Label groupTotalLabelPrototype) {
1785 this.groupTotalLabelPrototype = groupTotalLabelPrototype;
1786 }
1787
1788
1789
1790
1791
1792
1793
1794
1795 @BeanTagAttribute(name = "columnCalculations", type = BeanTagAttribute.AttributeType.LISTBEAN)
1796 public List<ColumnCalculationInfo> getColumnCalculations() {
1797 return columnCalculations;
1798 }
1799
1800
1801
1802
1803
1804
1805 public void setColumnCalculations(List<ColumnCalculationInfo> columnCalculations) {
1806 this.columnCalculations = columnCalculations;
1807 }
1808
1809
1810
1811
1812
1813
1814
1815
1816 @BeanTagAttribute(name = "renderOnlyLeftTotalLabels")
1817 public boolean isRenderOnlyLeftTotalLabels() {
1818 return renderOnlyLeftTotalLabels;
1819 }
1820
1821
1822
1823
1824
1825
1826 public void setRenderOnlyLeftTotalLabels(boolean renderOnlyLeftTotalLabels) {
1827 this.renderOnlyLeftTotalLabels = renderOnlyLeftTotalLabels;
1828 }
1829
1830
1831
1832
1833
1834
1835
1836 public List<Component> getFooterCalculationComponents() {
1837 return footerCalculationComponents;
1838 }
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854 @BeanTagAttribute(name = "groupingPropertyNames", type = BeanTagAttribute.AttributeType.LISTVALUE)
1855 public List<String> getGroupingPropertyNames() {
1856 return groupingPropertyNames;
1857 }
1858
1859
1860
1861
1862
1863
1864 public void setGroupingPropertyNames(List<String> groupingPropertyNames) {
1865 this.groupingPropertyNames = groupingPropertyNames;
1866 }
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877 @BeanTagAttribute(name = "groupingTitle")
1878 public String getGroupingTitle() {
1879 return groupingTitle;
1880 }
1881
1882
1883
1884
1885
1886
1887
1888 public void setGroupingTitle(String groupingTitle) {
1889 if (groupingTitle != null && !groupingTitle.contains("@{")) {
1890 throw new RuntimeException("groupingTitle MUST contain a springEL expression to uniquely"
1891 + " identify a collection group (often related to some value of the line). "
1892 + "Value provided: "
1893 + this.getGroupingTitle());
1894 }
1895 this.groupingTitle = groupingTitle;
1896 }
1897
1898
1899
1900
1901
1902
1903
1904 @BeanTagAttribute(name = "groupingPrefix")
1905 public String getGroupingPrefix() {
1906 return groupingPrefix;
1907 }
1908
1909
1910
1911
1912
1913
1914 public void setGroupingPrefix(String groupingPrefix) {
1915 this.groupingPrefix = groupingPrefix;
1916 }
1917
1918
1919
1920
1921
1922
1923
1924 public boolean isRowDetailsOpen() {
1925 return rowDetailsOpen;
1926 }
1927
1928
1929
1930
1931
1932
1933 public void setRowDetailsOpen(boolean rowDetailsOpen) {
1934 this.rowDetailsOpen = rowDetailsOpen;
1935 }
1936
1937
1938
1939
1940
1941
1942
1943 public boolean isShowToggleAllDetails() {
1944 return showToggleAllDetails;
1945 }
1946
1947
1948
1949
1950
1951
1952 public void setShowToggleAllDetails(boolean showToggleAllDetails) {
1953 this.showToggleAllDetails = showToggleAllDetails;
1954 }
1955
1956
1957
1958
1959
1960
1961
1962 public Action getToggleAllDetailsAction() {
1963 return toggleAllDetailsAction;
1964 }
1965
1966
1967
1968
1969
1970
1971
1972 public void setToggleAllDetailsAction(Action toggleAllDetailsAction) {
1973 this.toggleAllDetailsAction = toggleAllDetailsAction;
1974 }
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985 public boolean isAjaxDetailsRetrieval() {
1986 return ajaxDetailsRetrieval;
1987 }
1988
1989
1990
1991
1992
1993
1994 public void setAjaxDetailsRetrieval(boolean ajaxDetailsRetrieval) {
1995 this.ajaxDetailsRetrieval = ajaxDetailsRetrieval;
1996 }
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006 public Action getExpandDetailsActionPrototype() {
2007 return expandDetailsActionPrototype;
2008 }
2009
2010
2011
2012
2013
2014
2015 public int getGroupingColumnIndex() {
2016 return groupingColumnIndex;
2017 }
2018
2019
2020
2021
2022
2023
2024 public void setExpandDetailsActionPrototype(Action expandDetailsActionPrototype) {
2025 this.expandDetailsActionPrototype = expandDetailsActionPrototype;
2026 }
2027
2028
2029
2030
2031
2032
2033 public void setHeaderLabels(List<Label> headerLabels) {
2034 this.headerLabels = headerLabels;
2035 }
2036
2037
2038
2039
2040
2041
2042 public void setAllRowFields(List<Field> allRowFields) {
2043 this.allRowFields = allRowFields;
2044 }
2045
2046
2047
2048
2049
2050
2051 public void setFirstRowFields(List<Field> firstRowFields) {
2052 this.firstRowFields = firstRowFields;
2053 }
2054
2055
2056
2057
2058
2059
2060 public void setHeaderAdded(boolean headerAdded) {
2061 this.headerAdded = headerAdded;
2062 }
2063
2064
2065
2066
2067
2068
2069 public void setActionColumnIndex(int actionColumnIndex) {
2070 this.actionColumnIndex = actionColumnIndex;
2071 }
2072
2073
2074
2075
2076
2077
2078 public void setGroupingColumnIndex(int groupingColumnIndex) {
2079 this.groupingColumnIndex = groupingColumnIndex;
2080 }
2081
2082
2083
2084
2085
2086
2087 public void setGenerateGroupTotalRows(boolean generateGroupTotalRows) {
2088 this.generateGroupTotalRows = generateGroupTotalRows;
2089 }
2090
2091
2092
2093
2094
2095
2096 public void setColumnsToCalculate(List<String> columnsToCalculate) {
2097 this.columnsToCalculate = columnsToCalculate;
2098 }
2099
2100
2101
2102
2103
2104
2105 public void setFooterCalculationComponents(List<Component> footerCalculationComponents) {
2106 this.footerCalculationComponents = footerCalculationComponents;
2107 }
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121 @BeanTagAttribute(name = "conditionalRowCssClasses", type = BeanTagAttribute.AttributeType.MAPVALUE)
2122 public Map<String, String> getConditionalRowCssClasses() {
2123 return conditionalRowCssClasses;
2124 }
2125
2126
2127
2128
2129
2130
2131 public void setConditionalRowCssClasses(Map<String, String> conditionalRowCssClasses) {
2132 this.conditionalRowCssClasses = conditionalRowCssClasses;
2133 }
2134
2135
2136
2137
2138 @Override
2139 protected <T> void copyProperties(T layoutManager) {
2140 super.copyProperties(layoutManager);
2141 TableLayoutManager tableLayoutManagerCopy = (TableLayoutManager) layoutManager;
2142 tableLayoutManagerCopy.setUseShortLabels(this.isUseShortLabels());
2143 tableLayoutManagerCopy.setRepeatHeader(this.isRepeatHeader());
2144
2145 if (this.headerLabelPrototype != null) {
2146 tableLayoutManagerCopy.setHeaderLabelPrototype((Label) this.getHeaderLabelPrototype().copy());
2147 }
2148
2149 tableLayoutManagerCopy.setRenderSequenceField(this.isRenderSequenceField());
2150 tableLayoutManagerCopy.setGenerateAutoSequence(this.isGenerateAutoSequence());
2151
2152 if (this.sequenceFieldPrototype != null) {
2153 tableLayoutManagerCopy.setSequenceFieldPrototype((Field) this.getSequenceFieldPrototype().copy());
2154 }
2155
2156 if (this.actionFieldPrototype != null) {
2157 tableLayoutManagerCopy.setActionFieldPrototype((FieldGroup) this.getActionFieldPrototype().copy());
2158 }
2159
2160 if (this.subCollectionFieldGroupPrototype != null) {
2161 tableLayoutManagerCopy.setSubCollectionFieldGroupPrototype(
2162 (FieldGroup) this.getSubCollectionFieldGroupPrototype().copy());
2163 }
2164
2165 if (this.selectFieldPrototype != null) {
2166 tableLayoutManagerCopy.setSelectFieldPrototype((Field) this.getSelectFieldPrototype().copy());
2167 }
2168
2169 tableLayoutManagerCopy.setSeparateAddLine(this.isSeparateAddLine());
2170
2171 if (this.addLineGroup != null) {
2172 tableLayoutManagerCopy.setAddLineGroup((Group) this.getAddLineGroup().copy());
2173 }
2174
2175 tableLayoutManagerCopy.setNumberOfDataColumns(this.numberOfDataColumns);
2176
2177 if (this.headerLabels != null) {
2178 List<Label> headerLabelsCopy = Lists.newArrayListWithExpectedSize(this.headerLabels.size());
2179 for (Label headerLabel : headerLabels) {
2180 if (headerLabel != null) {
2181 headerLabelsCopy.add((Label) headerLabel.copy());
2182 }
2183 }
2184 tableLayoutManagerCopy.setHeaderLabels(headerLabelsCopy);
2185 }
2186
2187 if (this.allRowFields != null) {
2188 List<Field> allRowFieldsCopy = Lists.newArrayListWithExpectedSize(allRowFields.size());
2189 for (Field allRowField : allRowFields) {
2190 if (allRowField != null) {
2191 allRowFieldsCopy.add((Field) allRowField.copy());
2192 }
2193 }
2194 tableLayoutManagerCopy.setAllRowFields(allRowFieldsCopy);
2195 }
2196
2197 if (this.firstRowFields != null) {
2198 List<Field> firstRowFieldsCopy = Lists.newArrayListWithExpectedSize(firstRowFields.size());
2199 for (Field firstRowField : firstRowFields) {
2200 if (firstRowField != null) {
2201 firstRowFieldsCopy.add((Field) firstRowField.copy());
2202 }
2203 }
2204 tableLayoutManagerCopy.setFirstRowFields(firstRowFieldsCopy);
2205 }
2206
2207 if (this.pagerWidget != null) {
2208 tableLayoutManagerCopy.setPagerWidget((Pager)this.pagerWidget.copy());
2209 }
2210
2211 if (this.richTable != null) {
2212 tableLayoutManagerCopy.setRichTable((RichTable) this.getRichTable().copy());
2213 }
2214
2215 tableLayoutManagerCopy.setHeaderAdded(this.headerAdded);
2216 tableLayoutManagerCopy.setActionColumnIndex(this.getActionColumnIndex());
2217
2218 if (this.rowDetailsGroup != null) {
2219 tableLayoutManagerCopy.setRowDetailsGroup((Group) this.getRowDetailsGroup().copy());
2220 }
2221
2222 tableLayoutManagerCopy.setRowDetailsOpen(this.isRowDetailsOpen());
2223 tableLayoutManagerCopy.setShowToggleAllDetails(this.isShowToggleAllDetails());
2224
2225 if (this.toggleAllDetailsAction != null) {
2226 tableLayoutManagerCopy.setToggleAllDetailsAction((Action) this.getToggleAllDetailsAction().copy());
2227 }
2228
2229 tableLayoutManagerCopy.setAjaxDetailsRetrieval(this.isAjaxDetailsRetrieval());
2230
2231 if (this.expandDetailsActionPrototype != null) {
2232 tableLayoutManagerCopy.setExpandDetailsActionPrototype(
2233 (Action) this.getExpandDetailsActionPrototype().copy());
2234 }
2235
2236 tableLayoutManagerCopy.setGroupingTitle(this.getGroupingTitle());
2237 tableLayoutManagerCopy.setGroupingPrefix(this.getGroupingPrefix());
2238 tableLayoutManagerCopy.setGroupingColumnIndex(this.getGroupingColumnIndex());
2239
2240 if (this.groupingPropertyNames != null) {
2241 tableLayoutManagerCopy.setGroupingPropertyNames(new ArrayList<String>(groupingPropertyNames));
2242 }
2243
2244 tableLayoutManagerCopy.setRenderOnlyLeftTotalLabels(this.isRenderOnlyLeftTotalLabels());
2245 tableLayoutManagerCopy.setShowTotal(this.isShowTotal());
2246 tableLayoutManagerCopy.setShowPageTotal(this.isShowPageTotal());
2247 tableLayoutManagerCopy.setShowGroupTotal(this.isShowGroupTotal());
2248 tableLayoutManagerCopy.setGenerateGroupTotalRows(this.generateGroupTotalRows);
2249
2250 if (this.totalLabel != null) {
2251 tableLayoutManagerCopy.setTotalLabel((Label) this.getTotalLabel().copy());
2252 }
2253
2254 if (this.pageTotalLabel != null) {
2255 tableLayoutManagerCopy.setPageTotalLabel((Label) this.getPageTotalLabel().copy());
2256 }
2257
2258 if (this.groupTotalLabelPrototype != null) {
2259 tableLayoutManagerCopy.setGroupTotalLabelPrototype((Label) this.getGroupTotalLabelPrototype().copy());
2260 }
2261
2262 if (this.columnsToCalculate != null) {
2263 tableLayoutManagerCopy.setColumnsToCalculate(new ArrayList<String>(columnsToCalculate));
2264 }
2265
2266 if (this.columnCalculations != null) {
2267 List<ColumnCalculationInfo> columnCalculationsCopy = Lists.newArrayListWithExpectedSize(
2268 columnCalculations.size());
2269 for (ColumnCalculationInfo columnCalculation : columnCalculations) {
2270 columnCalculationsCopy.add((ColumnCalculationInfo) columnCalculation.copy());
2271 }
2272 tableLayoutManagerCopy.setColumnCalculations(columnCalculationsCopy);
2273 }
2274
2275 if (this.footerCalculationComponents != null) {
2276 List<Component> footerCalculationComponentsCopy = Lists.newArrayListWithExpectedSize(
2277 footerCalculationComponents.size());
2278 for (Component footerCalculationComponent : footerCalculationComponents) {
2279 if (footerCalculationComponent != null) {
2280 footerCalculationComponentsCopy.add((Component) footerCalculationComponent.copy());
2281 }
2282 }
2283 tableLayoutManagerCopy.setFooterCalculationComponents(footerCalculationComponentsCopy);
2284 }
2285
2286 if (this.conditionalRowCssClasses != null) {
2287 tableLayoutManagerCopy.setConditionalRowCssClasses(new HashMap<String, String>(
2288 this.conditionalRowCssClasses));
2289 }
2290 }
2291 }
2292