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