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