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 (isAddLine || ((!collectionGroup.isRenderAddLine() || collectionGroup.isReadOnly() || isSeparateAddLine())
203 && (lineIndex == 0))) {
204 if (isSuppressLineWrapping()) {
205 setNumberOfDataColumns(lineFields.size());
206 } else {
207 setNumberOfDataColumns(getNumberOfColumns());
208 }
209 }
210
211
212 if (!headerAdded) {
213 headerFields = new ArrayList<LabelField>();
214 dataFields = new ArrayList<Field>();
215
216 buildTableHeaderRows(collectionGroup, lineFields);
217 ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.LINE, currentLine);
218 ComponentUtils.pushObjectToContext(headerFields, UifConstants.ContextVariableNames.INDEX, new Integer(
219 lineIndex));
220 headerAdded = true;
221 }
222
223
224 for (Field field : lineFields) {
225 field.setLabelFieldRendered(true);
226
227
228
229 ComponentUtils.setComponentPropertyDeep(field, "summaryMessageField.render", new Boolean(false));
230 }
231
232 int rowCount = calculateNumberOfRows(collectionGroup.getItems());
233 int rowSpan = rowCount + subCollectionFields.size();
234
235
236 if (renderSequenceField) {
237 Field sequenceField = null;
238 if (!isAddLine) {
239 sequenceField = ComponentUtils.copy(sequenceFieldPrototype, idSuffix);
240
241 if (generateAutoSequence && (sequenceField instanceof MessageField)) {
242 ((MessageField) sequenceField).setMessageText(Integer.toString(lineIndex + 1));
243 }
244 }
245 else {
246 sequenceField = ComponentUtils.copy(collectionGroup.getAddLineLabelField(), idSuffix);
247 }
248 sequenceField.setRowSpan(rowSpan);
249
250 if (sequenceField instanceof DataBinding) {
251 ((DataBinding) sequenceField).getBindingInfo().setBindByNamePrefix(bindingPath);
252 }
253
254 ComponentUtils.updateContextForLine(sequenceField, currentLine, lineIndex);
255 dataFields.add(sequenceField);
256 }
257
258
259 if (collectionGroup.isRenderSelectField()) {
260 Field selectField = ComponentUtils.copy(selectFieldPrototype, idSuffix);
261 CollectionLayoutUtils.prepareSelectFieldForLine(selectField, collectionGroup, bindingPath, currentLine);
262
263 ComponentUtils.updateContextForLine(selectField, currentLine, lineIndex);
264 dataFields.add(selectField);
265 }
266
267
268 int cellPosition = 0;
269 for (Field lineField : lineFields) {
270 dataFields.add(lineField);
271
272 cellPosition += lineField.getColSpan();
273
274
275 if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions()
276 && !collectionGroup.isReadOnly()) {
277 FieldGroup lineActionsField = ComponentUtils.copy(actionFieldPrototype, idSuffix);
278
279 ComponentUtils.updateContextForLine(lineActionsField, currentLine, lineIndex);
280 lineActionsField.setRowSpan(rowSpan);
281 lineActionsField.setItems(actions);
282
283 dataFields.add(lineActionsField);
284 }
285 }
286
287
288 for (FieldGroup subCollectionField : subCollectionFields) {
289 subCollectionField.setColSpan(numberOfDataColumns);
290 }
291
292
293 dataFields.addAll(subCollectionFields);
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 protected void buildTableHeaderRows(CollectionGroup collectionGroup, List<Field> lineFields) {
317
318
319 int rowCount = calculateNumberOfRows(collectionGroup.getItems());
320
321
322 if (renderSequenceField) {
323 sequenceFieldPrototype.setLabelFieldRendered(true);
324 sequenceFieldPrototype.setRowSpan(rowCount);
325 addHeaderField(sequenceFieldPrototype, 1);
326 }
327
328
329 if (collectionGroup.isRenderSelectField()) {
330 selectFieldPrototype.setLabelFieldRendered(true);
331 selectFieldPrototype.setRowSpan(rowCount);
332 addHeaderField(selectFieldPrototype, 1);
333 }
334
335
336 int cellPosition = 0;
337 for (Field field : lineFields) {
338 if (!field.isRender() && StringUtils.isEmpty(field.getProgressiveRender())) {
339 continue;
340 }
341
342 cellPosition += field.getColSpan();
343 addHeaderField(field, cellPosition);
344
345
346 if ((cellPosition == getNumberOfDataColumns()) && collectionGroup.isRenderLineActions()
347 && !collectionGroup.isReadOnly()) {
348 actionFieldPrototype.setLabelFieldRendered(true);
349 actionFieldPrototype.setRowSpan(rowCount);
350 addHeaderField(actionFieldPrototype, cellPosition);
351 }
352 }
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366 protected void addHeaderField(Field field, int column) {
367 LabelField headerField = ComponentUtils.copy(headerFieldPrototype, "_c" + column);
368 if (useShortLabels) {
369 headerField.setLabelText(field.getLabel());
370 }
371 else {
372 headerField.setLabelText(field.getLabel());
373 }
374
375 headerField.setRowSpan(field.getRowSpan());
376 headerField.setColSpan(field.getColSpan());
377
378 if ((field.getRequired() != null) && field.getRequired().booleanValue()) {
379 headerField.getRequiredMessageField().setRender(true);
380 }
381 else {
382 headerField.getRequiredMessageField().setRender(false);
383 }
384
385 headerFields.add(headerField);
386 }
387
388
389
390
391
392
393
394
395
396
397 protected int calculateNumberOfRows(List<? extends Field> items) {
398 int rowCount = 0;
399
400
401 if (isSuppressLineWrapping()) {
402 return 1;
403 }
404
405 int cellCount = 0;
406 for (Field field : items) {
407 cellCount += field.getColSpan() + field.getRowSpan() - 1;
408 }
409
410 if (cellCount != 0) {
411 rowCount = cellCount / getNumberOfDataColumns();
412 }
413
414 return rowCount;
415 }
416
417
418
419
420 @Override
421 public Class<? extends Container> getSupportedContainer() {
422 return CollectionGroup.class;
423 }
424
425
426
427
428 @Override
429 public List<Component> getComponentsForLifecycle() {
430 List<Component> components = super.getComponentsForLifecycle();
431
432 components.add(richTable);
433 components.add(addLineGroup);
434 components.addAll(headerFields);
435 components.addAll(dataFields);
436
437 return components;
438 }
439
440
441
442
443 @Override
444 public List<Component> getComponentPrototypes() {
445 List<Component> components = super.getComponentPrototypes();
446
447 components.add(headerFieldPrototype);
448 components.add(sequenceFieldPrototype);
449 components.add(actionFieldPrototype);
450 components.add(subCollectionFieldGroupPrototype);
451 components.add(selectFieldPrototype);
452
453 return components;
454 }
455
456
457
458
459
460
461
462
463 public boolean isUseShortLabels() {
464 return this.useShortLabels;
465 }
466
467
468
469
470
471
472 public void setUseShortLabels(boolean useShortLabels) {
473 this.useShortLabels = useShortLabels;
474 }
475
476
477
478
479
480
481
482
483 public boolean isRepeatHeader() {
484 return this.repeatHeader;
485 }
486
487
488
489
490
491
492 public void setRepeatHeader(boolean repeatHeader) {
493 this.repeatHeader = repeatHeader;
494 }
495
496
497
498
499
500
501
502
503 public LabelField getHeaderFieldPrototype() {
504 return this.headerFieldPrototype;
505 }
506
507
508
509
510
511
512 public void setHeaderFieldPrototype(LabelField headerFieldPrototype) {
513 this.headerFieldPrototype = headerFieldPrototype;
514 }
515
516
517
518
519
520
521
522 public List<LabelField> getHeaderFields() {
523 return this.headerFields;
524 }
525
526
527
528
529
530
531
532 public boolean isRenderSequenceField() {
533 return this.renderSequenceField;
534 }
535
536
537
538
539
540
541 public void setRenderSequenceField(boolean renderSequenceField) {
542 this.renderSequenceField = renderSequenceField;
543 }
544
545
546
547
548
549
550
551
552 public String getSequencePropertyName() {
553 if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) {
554 return ((DataField) sequenceFieldPrototype).getPropertyName();
555 }
556
557 return null;
558 }
559
560
561
562
563
564
565 public void setSequencePropertyName(String sequencePropertyName) {
566 if ((sequenceFieldPrototype != null) && (sequenceFieldPrototype instanceof DataField)) {
567 ((DataField) sequenceFieldPrototype).setPropertyName(sequencePropertyName);
568 }
569 }
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584 public boolean isGenerateAutoSequence() {
585 return this.generateAutoSequence;
586 }
587
588
589
590
591
592
593 public void setGenerateAutoSequence(boolean generateAutoSequence) {
594 this.generateAutoSequence = generateAutoSequence;
595 }
596
597
598
599
600
601
602
603
604 public Field getSequenceFieldPrototype() {
605 return this.sequenceFieldPrototype;
606 }
607
608
609
610
611
612
613 public void setSequenceFieldPrototype(Field sequenceFieldPrototype) {
614 this.sequenceFieldPrototype = sequenceFieldPrototype;
615 }
616
617
618
619
620
621
622
623
624
625
626
627
628
629 public FieldGroup getActionFieldPrototype() {
630 return this.actionFieldPrototype;
631 }
632
633
634
635
636
637
638 public void setActionFieldPrototype(FieldGroup actionFieldPrototype) {
639 this.actionFieldPrototype = actionFieldPrototype;
640 }
641
642
643
644
645 public FieldGroup getSubCollectionFieldGroupPrototype() {
646 return this.subCollectionFieldGroupPrototype;
647 }
648
649
650
651
652
653
654 public void setSubCollectionFieldGroupPrototype(FieldGroup subCollectionFieldGroupPrototype) {
655 this.subCollectionFieldGroupPrototype = subCollectionFieldGroupPrototype;
656 }
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 public Field getSelectFieldPrototype() {
672 return selectFieldPrototype;
673 }
674
675
676
677
678
679
680 public void setSelectFieldPrototype(Field selectFieldPrototype) {
681 this.selectFieldPrototype = selectFieldPrototype;
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697 public boolean isSeparateAddLine() {
698 return separateAddLine;
699 }
700
701
702
703
704
705
706 public void setSeparateAddLine(boolean separateAddLine) {
707 this.separateAddLine = separateAddLine;
708 }
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724 public Group getAddLineGroup() {
725 return addLineGroup;
726 }
727
728
729
730
731
732
733 public void setAddLineGroup(Group addLineGroup) {
734 this.addLineGroup = addLineGroup;
735 }
736
737
738
739
740
741
742
743 public List<Field> getDataFields() {
744 return this.dataFields;
745 }
746
747
748
749
750
751
752
753 public RichTable getRichTable() {
754 return this.richTable;
755 }
756
757
758
759
760
761
762 public void setRichTable(RichTable richTable) {
763 this.richTable = richTable;
764 }
765
766
767
768
769 public int getNumberOfDataColumns() {
770 return this.numberOfDataColumns;
771 }
772
773
774
775
776 public void setNumberOfDataColumns(int numberOfDataColumns) {
777 this.numberOfDataColumns = numberOfDataColumns;
778 }
779
780 }