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.krad.uif.UifConstants;
20 import org.kuali.rice.krad.uif.component.DataBinding;
21 import org.kuali.rice.krad.uif.container.CollectionGroup;
22 import org.kuali.rice.krad.uif.container.Container;
23 import org.kuali.rice.krad.uif.container.Group;
24 import org.kuali.rice.krad.uif.field.DataField;
25 import org.kuali.rice.krad.uif.field.FieldGroup;
26 import org.kuali.rice.krad.uif.field.InputField;
27 import org.kuali.rice.krad.uif.view.View;
28 import org.kuali.rice.krad.uif.component.Component;
29 import org.kuali.rice.krad.uif.field.ActionField;
30 import org.kuali.rice.krad.uif.field.Field;
31 import org.kuali.rice.krad.uif.field.LabelField;
32 import org.kuali.rice.krad.uif.field.MessageField;
33 import org.kuali.rice.krad.uif.util.ComponentFactory;
34 import org.kuali.rice.krad.uif.util.ComponentUtils;
35 import org.kuali.rice.krad.uif.widget.RichTable;
36 import org.kuali.rice.krad.web.form.UifFormBase;
37
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Set;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class TableLayoutManager extends GridLayoutManager implements CollectionLayoutManager {
58 private static final long serialVersionUID = 3622267585541524208L;
59
60 private boolean useShortLabels;
61 private boolean repeatHeader;
62 private LabelField headerFieldPrototype;
63
64 private boolean renderSequenceField;
65 private boolean generateAutoSequence;
66 private Field sequenceFieldPrototype;
67
68 private FieldGroup actionFieldPrototype;
69 private FieldGroup subCollectionFieldGroupPrototype;
70 private Field selectFieldPrototype;
71
72 private boolean separateAddLine;
73 private Group addLineGroup;
74
75
76 private int numberOfDataColumns;
77
78 private List<LabelField> headerFields;
79 private List<Field> dataFields;
80
81 private RichTable richTable;
82 private boolean headerAdded = false;
83
84 private Set<String> hiddenColumns;
85 private Set<String> sortableColumns;
86
87 public TableLayoutManager() {
88 useShortLabels = true;
89 repeatHeader = false;
90 renderSequenceField = true;
91 generateAutoSequence = false;
92 separateAddLine = false;
93
94 headerFields = new ArrayList<LabelField>();
95 dataFields = new ArrayList<Field>();
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109 @Override
110 public void performInitialization(View view, Object model, Container container) {
111 super.performInitialization(view, model, container);
112
113 if (generateAutoSequence && !(sequenceFieldPrototype instanceof MessageField)) {
114 sequenceFieldPrototype = ComponentFactory.getMessageField();
115 view.assignComponentIds(sequenceFieldPrototype);
116 }
117
118 view.getViewHelperService().performComponentInitialization(view, model, headerFieldPrototype);
119 view.getViewHelperService().performComponentInitialization(view, model, sequenceFieldPrototype);
120 view.getViewHelperService().performComponentInitialization(view, model, actionFieldPrototype);
121 view.getViewHelperService().performComponentInitialization(view, model, subCollectionFieldGroupPrototype);
122 view.getViewHelperService().performComponentInitialization(view, model, selectFieldPrototype);
123 }
124
125
126
127
128
129
130
131
132 @Override
133 public void performFinalize(View view, Object model, Container container) {
134 super.performFinalize(view, model, container);
135
136 UifFormBase formBase = (UifFormBase) model;
137
138 CollectionGroup collectionGroup = (CollectionGroup) container;
139
140 int totalColumns = getNumberOfDataColumns();
141 if (renderSequenceField) {
142 totalColumns++;
143 }
144
145 if (collectionGroup.isRenderSelectField()) {
146 totalColumns++;
147 }
148
149 if (collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly()) {
150 totalColumns++;
151 }
152
153 if (collectionGroup.isRenderAddLine()){
154 if(StringUtils.isBlank(this.getFirstLineStyle()) && !isSeparateAddLine()){
155 this.setFirstLineStyle("kr-addLine");
156 }
157 }
158
159
160 if (UifConstants.ActionEvents.ADD_LINE.equals(formBase.getActionEvent())) {
161 String highlightScript =
162 "jq(\"#" + container.getId() + "_div > tr:first\").effect(\"highlight\",{}, 6000);";
163 String onReadyScript = collectionGroup.getOnDocumentReadyScript();
164 if (StringUtils.isNotBlank(onReadyScript)) {
165 highlightScript = onReadyScript + highlightScript;
166 }
167 collectionGroup.setOnDocumentReadyScript(highlightScript);
168 }
169 setNumberOfColumns(totalColumns);
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184 public void buildLine(View view, Object model, CollectionGroup collectionGroup, List<Field> lineFields,
185 List<FieldGroup> subCollectionFields, String bindingPath, List<ActionField> actions, String idSuffix,
186 Object currentLine, int lineIndex) {
187 boolean isAddLine = lineIndex == -1;
188
189
190 if (isAddLine && separateAddLine) {
191 if (StringUtils.isBlank(addLineGroup.getTitle()) && StringUtils.isBlank(
192 addLineGroup.getHeader().getHeaderText())) {
193 addLineGroup.getHeader().setHeaderText(collectionGroup.getAddLineLabel());
194 }
195
196 addLineGroup.setItems(lineFields);
197
198 List<Component> footerItems = new ArrayList<Component>(actions);
199 footerItems.addAll(addLineGroup.getFooter().getItems());
200 addLineGroup.getFooter().setItems(footerItems);
201
202 return;
203 }
204
205
206 if (dataFields.isEmpty()) {
207 if (isSuppressLineWrapping()) {
208 setNumberOfDataColumns(lineFields.size());
209 } else {
210 setNumberOfDataColumns(getNumberOfColumns());
211 }
212 }
213
214
215 if (!headerAdded) {
216 headerFields = new ArrayList<LabelField>();
217 dataFields = new ArrayList<Field>();
218
219 buildTableHeaderRows(collectionGroup, lineFields);
220 ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.LINE, currentLine);
221 ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.INDEX, new Integer(
222 lineIndex));
223 headerAdded = true;
224 }
225
226
227 for (Field field : lineFields) {
228 field.setLabelFieldRendered(true);
229
230
231
232 ComponentUtils.setComponentPropertyDeep(field, "summaryMessageField.render", new Boolean(false));
233 }
234
235 int rowCount = calculateNumberOfRows(lineFields);
236 int rowSpan = rowCount + subCollectionFields.size();
237
238
239 if (renderSequenceField) {
240 Field sequenceField = null;
241 if (!isAddLine) {
242 sequenceField = ComponentUtils.copy(sequenceFieldPrototype, idSuffix);
243
244 if (generateAutoSequence && (sequenceField instanceof MessageField)) {
245 ((MessageField) sequenceField).setMessageText(Integer.toString(lineIndex + 1));
246 }
247 }
248 else {
249 sequenceField = ComponentUtils.copy(collectionGroup.getAddLineLabelField(), idSuffix);
250 }
251 sequenceField.setRowSpan(rowSpan);
252
253 if (sequenceField instanceof DataBinding) {
254 ((DataBinding) sequenceField).getBindingInfo().setBindByNamePrefix(bindingPath);
255 }
256
257 ComponentUtils.updateContextForLine(sequenceField, currentLine, lineIndex);
258 dataFields.add(sequenceField);
259 }
260
261
262 if (collectionGroup.isRenderSelectField()) {
263 Field selectField = ComponentUtils.copy(selectFieldPrototype, idSuffix);
264 CollectionLayoutUtils.prepareSelectFieldForLine(selectField, collectionGroup, bindingPath, currentLine);
265
266 ComponentUtils.updateContextForLine(selectField, currentLine, lineIndex);
267 dataFields.add(selectField);
268 }
269
270
271 int cellPosition = 0;
272 for (Field lineField : lineFields) {
273 dataFields.add(lineField);
274
275 cellPosition += lineField.getColSpan();
276
277
278 if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions()
279 && !collectionGroup.isReadOnly()) {
280 FieldGroup lineActionsField = ComponentUtils.copy(actionFieldPrototype, idSuffix);
281
282 ComponentUtils.updateContextForLine(lineActionsField, currentLine, lineIndex);
283 lineActionsField.setRowSpan(rowSpan);
284 lineActionsField.setItems(actions);
285
286 dataFields.add(lineActionsField);
287 }
288 }
289
290
291 for (FieldGroup subCollectionField : subCollectionFields) {
292 subCollectionField.setColSpan(numberOfDataColumns);
293 }
294
295
296 dataFields.addAll(subCollectionFields);
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 protected void buildTableHeaderRows(CollectionGroup collectionGroup, List<Field> lineFields) {
320
321
322 int rowCount = calculateNumberOfRows(lineFields);
323
324
325 if (renderSequenceField) {
326 sequenceFieldPrototype.setLabelFieldRendered(true);
327 sequenceFieldPrototype.setRowSpan(rowCount);
328 addHeaderField(sequenceFieldPrototype, 1);
329 }
330
331
332 if (collectionGroup.isRenderSelectField()) {
333 selectFieldPrototype.setLabelFieldRendered(true);
334 selectFieldPrototype.setRowSpan(rowCount);
335 addHeaderField(selectFieldPrototype, 1);
336 }
337
338
339 int cellPosition = 0;
340 for (Field field : lineFields) {
341 if (!field.isRender() && StringUtils.isEmpty(field.getProgressiveRender())) {
342 continue;
343 }
344
345 cellPosition += field.getColSpan();
346 addHeaderField(field, cellPosition);
347
348
349 if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions()
350 && !collectionGroup.isReadOnly()) {
351 actionFieldPrototype.setLabelFieldRendered(true);
352 actionFieldPrototype.setRowSpan(rowCount);
353 addHeaderField(actionFieldPrototype, cellPosition);
354 }
355 }
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369 protected void addHeaderField(Field field, int column) {
370 LabelField headerField = ComponentUtils.copy(headerFieldPrototype, "_c" + column);
371 if (useShortLabels) {
372 headerField.setLabelText(field.getLabel());
373 }
374 else {
375 headerField.setLabelText(field.getLabel());
376 }
377
378 headerField.setRowSpan(field.getRowSpan());
379 headerField.setColSpan(field.getColSpan());
380
381 if ((field.getRequired() != null) && field.getRequired().booleanValue()) {
382 headerField.getRequiredMessageField().setRender(true);
383 }
384 else {
385 headerField.getRequiredMessageField().setRender(false);
386 }
387
388 headerFields.add(headerField);
389 }
390
391
392
393
394
395
396
397
398
399
400 protected int calculateNumberOfRows(List<? extends Field> items) {
401 int rowCount = 0;
402
403
404 if (isSuppressLineWrapping()) {
405 return 1;
406 }
407
408 int cellCount = 0;
409 for (Field field : items) {
410 cellCount += field.getColSpan() + field.getRowSpan() - 1;
411 }
412
413 if (cellCount != 0) {
414 rowCount = cellCount / getNumberOfDataColumns();
415 }
416
417 return rowCount;
418 }
419
420
421
422
423 @Override
424 public Class<? extends Container> getSupportedContainer() {
425 return CollectionGroup.class;
426 }
427
428
429
430
431 @Override
432 public List<Component> getComponentsForLifecycle() {
433 List<Component> components = super.getComponentsForLifecycle();
434
435 components.add(richTable);
436 components.add(addLineGroup);
437 components.addAll(headerFields);
438 components.addAll(dataFields);
439
440 return components;
441 }
442
443
444
445
446 @Override
447 public List<Component> getComponentPrototypes() {
448 List<Component> components = super.getComponentPrototypes();
449
450 components.add(headerFieldPrototype);
451 components.add(sequenceFieldPrototype);
452 components.add(actionFieldPrototype);
453 components.add(subCollectionFieldGroupPrototype);
454 components.add(selectFieldPrototype);
455
456 return components;
457 }
458
459
460
461
462
463
464
465
466 public boolean isUseShortLabels() {
467 return this.useShortLabels;
468 }
469
470
471
472
473
474
475 public void setUseShortLabels(boolean useShortLabels) {
476 this.useShortLabels = useShortLabels;
477 }
478
479
480
481
482
483
484
485
486 public boolean isRepeatHeader() {
487 return this.repeatHeader;
488 }
489
490
491
492
493
494
495 public void setRepeatHeader(boolean repeatHeader) {
496 this.repeatHeader = repeatHeader;
497 }
498
499
500
501
502
503
504
505
506 public LabelField getHeaderFieldPrototype() {
507 return this.headerFieldPrototype;
508 }
509
510
511
512
513
514
515 public void setHeaderFieldPrototype(LabelField headerFieldPrototype) {
516 this.headerFieldPrototype = headerFieldPrototype;
517 }
518
519
520
521
522
523
524
525 public List<LabelField> getHeaderFields() {
526 return this.headerFields;
527 }
528
529
530
531
532
533
534
535 public boolean isRenderSequenceField() {
536 return this.renderSequenceField;
537 }
538
539
540
541
542
543
544 public void setRenderSequenceField(boolean renderSequenceField) {
545 this.renderSequenceField = renderSequenceField;
546 }
547
548
549
550
551
552
553
554
555 public String getSequencePropertyName() {
556 if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) {
557 return ((DataField) sequenceFieldPrototype).getPropertyName();
558 }
559
560 return null;
561 }
562
563
564
565
566
567
568 public void setSequencePropertyName(String sequencePropertyName) {
569 if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) {
570 ((DataField) sequenceFieldPrototype).setPropertyName(sequencePropertyName);
571 }
572 }
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587 public boolean isGenerateAutoSequence() {
588 return this.generateAutoSequence;
589 }
590
591
592
593
594
595
596 public void setGenerateAutoSequence(boolean generateAutoSequence) {
597 this.generateAutoSequence = generateAutoSequence;
598 }
599
600
601
602
603
604
605
606
607 public Field getSequenceFieldPrototype() {
608 return this.sequenceFieldPrototype;
609 }
610
611
612
613
614
615
616 public void setSequenceFieldPrototype(Field sequenceFieldPrototype) {
617 this.sequenceFieldPrototype = sequenceFieldPrototype;
618 }
619
620
621
622
623
624
625
626
627
628
629
630
631
632 public FieldGroup getActionFieldPrototype() {
633 return this.actionFieldPrototype;
634 }
635
636
637
638
639
640
641 public void setActionFieldPrototype(FieldGroup actionFieldPrototype) {
642 this.actionFieldPrototype = actionFieldPrototype;
643 }
644
645
646
647
648 public FieldGroup getSubCollectionFieldGroupPrototype() {
649 return this.subCollectionFieldGroupPrototype;
650 }
651
652
653
654
655
656
657 public void setSubCollectionFieldGroupPrototype(FieldGroup subCollectionFieldGroupPrototype) {
658 this.subCollectionFieldGroupPrototype = subCollectionFieldGroupPrototype;
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674 public Field getSelectFieldPrototype() {
675 return selectFieldPrototype;
676 }
677
678
679
680
681
682
683 public void setSelectFieldPrototype(Field selectFieldPrototype) {
684 this.selectFieldPrototype = selectFieldPrototype;
685 }
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700 public boolean isSeparateAddLine() {
701 return separateAddLine;
702 }
703
704
705
706
707
708
709 public void setSeparateAddLine(boolean separateAddLine) {
710 this.separateAddLine = separateAddLine;
711 }
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 public Group getAddLineGroup() {
728 return addLineGroup;
729 }
730
731
732
733
734
735
736 public void setAddLineGroup(Group addLineGroup) {
737 this.addLineGroup = addLineGroup;
738 }
739
740
741
742
743
744
745
746 public List<Field> getDataFields() {
747 return this.dataFields;
748 }
749
750
751
752
753
754
755
756 public RichTable getRichTable() {
757 return this.richTable;
758 }
759
760
761
762
763
764
765 public void setRichTable(RichTable richTable) {
766 this.richTable = richTable;
767 }
768
769
770
771
772 public int getNumberOfDataColumns() {
773 return this.numberOfDataColumns;
774 }
775
776
777
778
779 public void setNumberOfDataColumns(int numberOfDataColumns) {
780 this.numberOfDataColumns = numberOfDataColumns;
781 }
782
783
784 public Set<String> getHiddenColumns() {
785 return hiddenColumns;
786 }
787
788 public void setHiddenColumns(Set<String> hiddenColumns) {
789 this.hiddenColumns = hiddenColumns;
790 }
791
792
793 public Set<String> getSortableColumns() {
794 return sortableColumns;
795 }
796
797 public void setSortableColumns(Set<String> sortableColumns) {
798 this.sortableColumns = sortableColumns;
799 }
800 }