1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.widget;
17
18 import org.apache.commons.lang.ClassUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.util.type.KualiDecimal;
21 import org.kuali.rice.core.api.util.type.KualiInteger;
22 import org.kuali.rice.core.api.util.type.KualiPercent;
23 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
24 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
25 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
26 import org.kuali.rice.krad.uif.UifConstants;
27 import org.kuali.rice.krad.uif.component.Component;
28 import org.kuali.rice.krad.uif.container.CollectionGroup;
29 import org.kuali.rice.krad.uif.control.CheckboxControl;
30 import org.kuali.rice.krad.uif.control.CheckboxGroupControl;
31 import org.kuali.rice.krad.uif.control.Control;
32 import org.kuali.rice.krad.uif.control.RadioGroupControl;
33 import org.kuali.rice.krad.uif.control.SelectControl;
34 import org.kuali.rice.krad.uif.field.DataField;
35 import org.kuali.rice.krad.uif.field.FieldGroup;
36 import org.kuali.rice.krad.uif.field.InputField;
37 import org.kuali.rice.krad.uif.field.MessageField;
38 import org.kuali.rice.krad.uif.layout.LayoutManager;
39 import org.kuali.rice.krad.uif.layout.TableLayoutManager;
40 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
41 import org.kuali.rice.krad.uif.view.View;
42 import org.kuali.rice.krad.web.form.UifFormBase;
43
44 import java.sql.Timestamp;
45 import java.util.List;
46 import java.util.Set;
47
48
49
50
51
52
53
54
55
56
57
58 @BeanTags({@BeanTag(name = "richTable-bean", parent = "Uif-RichTable"),
59 @BeanTag(name = "pagedRichTable-bean", parent = "Uif-PagedRichTable"),
60 @BeanTag(name = "scrollableRichTable-bean", parent = "Uif-ScrollableRichTable")})
61 public class RichTable extends WidgetBase {
62 private static final long serialVersionUID = 4671589690877390070L;
63
64 private String emptyTableMessage;
65 private boolean disableTableSort;
66
67 private boolean forceAoColumnDefsOverride;
68
69 private Set<String> hiddenColumns;
70 private Set<String> sortableColumns;
71
72 private String ajaxSource;
73
74 private boolean showSearchAndExportOptions = true;
75
76 private String groupingOptionsJSString;
77
78 public RichTable() {
79 super();
80 groupingOptionsJSString = "null";
81 }
82
83
84
85
86
87
88
89
90 @Override
91 public void performFinalize(View view, Object model, Component component) {
92 super.performFinalize(view, model, component);
93
94 UifFormBase formBase = (UifFormBase) model;
95
96 if (isRender()) {
97 if (StringUtils.isNotBlank(getEmptyTableMessage()) && !getTemplateOptions().containsKey(
98 UifConstants.TableToolsKeys.LANGUAGE)) {
99 getTemplateOptions().put(UifConstants.TableToolsKeys.LANGUAGE,
100 "{\"" + UifConstants.TableToolsKeys.EMPTY_TABLE + "\" : \"" + getEmptyTableMessage() + "\"}");
101 }
102
103 if (!isShowSearchAndExportOptions()) {
104 Object domOption = getTemplateOptions().get(UifConstants.TableToolsKeys.SDOM);
105 if (domOption instanceof String) {
106 String sDomOption = (String) domOption;
107
108 if (StringUtils.isNotBlank(sDomOption)) {
109 sDomOption = StringUtils.remove(sDomOption, "T");
110 sDomOption = StringUtils.remove(sDomOption, "f");
111 getTemplateOptions().put(UifConstants.TableToolsKeys.SDOM, sDomOption);
112 }
113 }
114 }
115
116
117 if (UifConstants.ActionEvents.ADD_LINE.equals(formBase.getActionEvent()) || UifConstants.ActionEvents
118 .ADD_BLANK_LINE.equals(formBase.getActionEvent())) {
119 getTemplateOptions().put(UifConstants.TableToolsKeys.AASORTING, "[]");
120 }
121
122 if ((component instanceof CollectionGroup)) {
123 buildTableOptions((CollectionGroup) component);
124 setTotalOptions((CollectionGroup) component);
125 }
126
127 if (isDisableTableSort()) {
128 getTemplateOptions().put(UifConstants.TableToolsKeys.TABLE_SORT, "false");
129 }
130
131 if (StringUtils.isNotBlank(ajaxSource)) {
132 getTemplateOptions().put(UifConstants.TableToolsKeys.SAJAX_SOURCE, ajaxSource);
133 }
134 }
135 }
136
137
138
139
140
141
142 private void setTotalOptions(CollectionGroup collectionGroup) {
143 LayoutManager layoutManager = collectionGroup.getLayoutManager();
144
145 if (layoutManager instanceof TableLayoutManager) {
146 List<String> totalColumns = ((TableLayoutManager) layoutManager).getColumnsToCalculate();
147
148 if (totalColumns.size() > 0) {
149 String array = "[";
150
151 for (String i : totalColumns) {
152 array = array + i + ",";
153 }
154 array = StringUtils.removeEnd(array, ",");
155 array = array + "]";
156 getTemplateOptions().put(UifConstants.TableToolsKeys.FOOTER_CALLBACK,
157 "function (nRow, aaData, iStart, iEnd, aiDisplay) {initializeTotalsFooter (nRow, aaData, iStart, iEnd, aiDisplay, "
158 + array
159 + " )}");
160 }
161 }
162 }
163
164
165
166
167
168
169 protected void buildTableOptions(CollectionGroup collectionGroup) {
170 LayoutManager layoutManager = collectionGroup.getLayoutManager();
171
172
173 if (!collectionGroup.getSubCollections().isEmpty()) {
174 setDisableTableSort(true);
175 }
176
177 if (!isDisableTableSort()) {
178
179 if (collectionGroup.isRenderAddLine()
180 && !collectionGroup.isReadOnly()
181 && !((layoutManager instanceof TableLayoutManager) && ((TableLayoutManager) layoutManager)
182 .isSeparateAddLine())) {
183 getTemplateOptions().put(UifConstants.TableToolsKeys.SORT_SKIP_ROWS,
184 "[" + UifConstants.TableToolsValues.ADD_ROW_DEFAULT_INDEX + "]");
185 }
186
187 StringBuffer tableToolsColumnOptions = new StringBuffer("[");
188
189 int columnIndex = 0;
190 int actionIndex = -1;
191 boolean actionFieldVisible = collectionGroup.isRenderLineActions() && !collectionGroup.isReadOnly();
192
193 if (layoutManager instanceof TableLayoutManager) {
194 actionIndex = ((TableLayoutManager) layoutManager).getActionColumnIndex();
195 }
196
197 if (actionIndex == 1 && actionFieldVisible) {
198 String actionColOptions = constructTableColumnOptions(columnIndex, false, null, null);
199 tableToolsColumnOptions.append(actionColOptions + " , ");
200 columnIndex++;
201 }
202
203 if (layoutManager instanceof TableLayoutManager && ((TableLayoutManager) layoutManager)
204 .isRenderSequenceField()) {
205 tableToolsColumnOptions.append("{\""
206 + UifConstants.TableToolsKeys.SORT_TYPE
207 + "\" : \""
208 + UifConstants.TableToolsValues.NUMERIC
209 + "\", "
210 + "\""
211 + UifConstants.TableToolsKeys.TARGETS
212 + "\": ["
213 + columnIndex
214 + "]}, ");
215 columnIndex++;
216 if (actionIndex == 2 && actionFieldVisible) {
217 String actionColOptions = constructTableColumnOptions(columnIndex, false, null, null);
218 tableToolsColumnOptions.append(actionColOptions + " , ");
219 columnIndex++;
220 }
221 }
222
223
224 if (collectionGroup.isIncludeLineSelectionField()) {
225 String colOptions = constructTableColumnOptions(columnIndex, false, null, null);
226 tableToolsColumnOptions.append(colOptions + " , ");
227 columnIndex++;
228 }
229
230
231 if (!StringUtils.isEmpty(getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMNS))) {
232
233 String jsArray = getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMNS);
234 int startBrace = StringUtils.indexOf(jsArray, "[");
235 int endBrace = StringUtils.lastIndexOf(jsArray, "]");
236 tableToolsColumnOptions.append(StringUtils.substring(jsArray, startBrace + 1, endBrace) + ", ");
237
238 if (actionFieldVisible && (actionIndex == -1 || actionIndex >= columnIndex)) {
239 String actionColOptions = constructTableColumnOptions(actionIndex, false, null, null);
240 tableToolsColumnOptions.append(actionColOptions);
241 } else {
242 tableToolsColumnOptions = new StringBuffer(StringUtils.removeEnd(tableToolsColumnOptions.toString(),
243 ", "));
244 }
245
246 tableToolsColumnOptions.append("]");
247 getTemplateOptions().put(UifConstants.TableToolsKeys.AO_COLUMNS, tableToolsColumnOptions.toString());
248 } else if (!StringUtils.isEmpty(getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMN_DEFS))
249 && forceAoColumnDefsOverride) {
250 String jsArray = getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMN_DEFS);
251 int startBrace = StringUtils.indexOf(jsArray, "[");
252 int endBrace = StringUtils.lastIndexOf(jsArray, "]");
253 tableToolsColumnOptions.append(StringUtils.substring(jsArray, startBrace + 1, endBrace) + ", ");
254
255 if (actionFieldVisible && (actionIndex == -1 || actionIndex >= columnIndex)) {
256 String actionColOptions = constructTableColumnOptions(actionIndex, false, null, null);
257 tableToolsColumnOptions.append(actionColOptions);
258 } else {
259 tableToolsColumnOptions = new StringBuffer(StringUtils.removeEnd(tableToolsColumnOptions.toString(),
260 ", "));
261 }
262
263 tableToolsColumnOptions.append("]");
264 getTemplateOptions().put(UifConstants.TableToolsKeys.AO_COLUMN_DEFS,
265 tableToolsColumnOptions.toString());
266 } else {
267
268
269 for (Component component : collectionGroup.getItems()) {
270 if (actionFieldVisible && columnIndex + 1 == actionIndex) {
271 String actionColOptions = constructTableColumnOptions(columnIndex, false, null, null);
272 tableToolsColumnOptions.append(actionColOptions + " , ");
273 columnIndex++;
274 }
275
276 if (component instanceof FieldGroup) {
277 component = ((FieldGroup) component).getItems().get(0);
278 }
279
280 if (component instanceof DataField) {
281 DataField field = (DataField) component;
282
283
284 if (getHiddenColumns() != null && getHiddenColumns().contains(field.getPropertyName())) {
285 tableToolsColumnOptions.append("{"
286 + UifConstants.TableToolsKeys.VISIBLE
287 + ": "
288 + UifConstants.TableToolsValues.FALSE
289 + ", \""
290 + UifConstants.TableToolsKeys.TARGETS
291 + "\": ["
292 + columnIndex
293 + "]"
294 + "}, ");
295
296 } else if (getSortableColumns() != null && !getSortableColumns().isEmpty()) {
297 if (getSortableColumns().contains(field.getPropertyName())) {
298 tableToolsColumnOptions.append(getDataFieldColumnOptions(columnIndex, collectionGroup,
299 field) + ", ");
300 } else {
301 tableToolsColumnOptions.append("{'"
302 + UifConstants.TableToolsKeys.SORTABLE
303 + "': "
304 + UifConstants.TableToolsValues.FALSE
305 + ", \""
306 + UifConstants.TableToolsKeys.TARGETS
307 + "\": ["
308 + columnIndex
309 + "]"
310 + "}, ");
311 }
312 } else {
313 String colOptions = getDataFieldColumnOptions(columnIndex, collectionGroup, field);
314 tableToolsColumnOptions.append(colOptions + " , ");
315 }
316 columnIndex++;
317 } else if (component instanceof MessageField
318 && component.getDataAttributes().get("role") != null
319 && component.getDataAttributes().get("role").equals("grouping")) {
320
321 tableToolsColumnOptions.append("{"
322 + UifConstants.TableToolsKeys.VISIBLE
323 + ": "
324 + UifConstants.TableToolsValues.FALSE
325 + ", \""
326 + UifConstants.TableToolsKeys.TARGETS
327 + "\": ["
328 + columnIndex
329 + "]"
330 + "}, ");
331 columnIndex++;
332 } else {
333 String colOptions = constructTableColumnOptions(columnIndex, false, null, null);
334 tableToolsColumnOptions.append(colOptions + " , ");
335 columnIndex++;
336 }
337
338 }
339
340 if (actionFieldVisible && (actionIndex == -1 || actionIndex >= columnIndex)) {
341 String actionColOptions = constructTableColumnOptions(actionIndex, false, null, null);
342 tableToolsColumnOptions.append(actionColOptions);
343 } else {
344 tableToolsColumnOptions = new StringBuffer(StringUtils.removeEnd(tableToolsColumnOptions.toString(),
345 ", "));
346 }
347
348 if (!StringUtils.isEmpty(getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMN_DEFS))) {
349 String origAoOptions = getTemplateOptions().get(UifConstants.TableToolsKeys.AO_COLUMN_DEFS).trim();
350 origAoOptions = StringUtils.removeStart(origAoOptions, "[");
351 origAoOptions = StringUtils.removeEnd(origAoOptions, "]");
352 tableToolsColumnOptions.append("," + origAoOptions);
353 }
354 tableToolsColumnOptions.append("]");
355 getTemplateOptions().put(UifConstants.TableToolsKeys.AO_COLUMN_DEFS,
356 tableToolsColumnOptions.toString());
357 }
358 }
359 }
360
361
362
363
364
365
366
367
368 protected String getDataFieldColumnOptions(int target, CollectionGroup collectionGroup, DataField field) {
369 String sortType = null;
370
371 if (!collectionGroup.isReadOnly()
372 && (field instanceof InputField)
373 && ((InputField) field).getControl() != null) {
374 Control control = ((InputField) field).getControl();
375 if (control instanceof SelectControl) {
376 sortType = UifConstants.TableToolsValues.DOM_SELECT;
377 } else if (control instanceof CheckboxControl || control instanceof CheckboxGroupControl) {
378 sortType = UifConstants.TableToolsValues.DOM_CHECK;
379 } else if (control instanceof RadioGroupControl) {
380 sortType = UifConstants.TableToolsValues.DOM_RADIO;
381 } else {
382 sortType = UifConstants.TableToolsValues.DOM_TEXT;
383 }
384 } else {
385 sortType = UifConstants.TableToolsValues.DOM_TEXT;
386 }
387
388 Class dataTypeClass = ObjectPropertyUtils.getPropertyType(collectionGroup.getCollectionObjectClass(),
389 field.getPropertyName());
390
391 return constructTableColumnOptions(target, true, dataTypeClass, sortType);
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405 protected String constructTableColumnOptions(int target, boolean isSortable, Class dataTypeClass,
406 String sortDataType) {
407 String colOptions = "null";
408
409 String sortType = "";
410 if (!isSortable || dataTypeClass == null || sortType == null) {
411 colOptions = "\"" + UifConstants.TableToolsKeys.SORTABLE + "\" : false, \"sType\" : \"string\"";
412 } else {
413 if (ClassUtils.isAssignable(dataTypeClass, KualiPercent.class)) {
414 sortType = UifConstants.TableToolsValues.PERCENT;
415 } else if (ClassUtils.isAssignable(dataTypeClass, KualiInteger.class) || ClassUtils.isAssignable(
416 dataTypeClass, KualiDecimal.class)) {
417 sortType = UifConstants.TableToolsValues.CURRENCY;
418 } else if (ClassUtils.isAssignable(dataTypeClass, Timestamp.class)) {
419 sortType = "date";
420 } else if (ClassUtils.isAssignable(dataTypeClass, java.sql.Date.class) || ClassUtils.isAssignable(
421 dataTypeClass, java.util.Date.class)) {
422 sortType = UifConstants.TableToolsValues.DATE;
423 } else if (ClassUtils.isAssignable(dataTypeClass, Number.class)) {
424 sortType = UifConstants.TableToolsValues.NUMERIC;
425 } else {
426 sortType = UifConstants.TableToolsValues.STRING;
427 }
428
429 colOptions = "\"" + UifConstants.TableToolsKeys.SORT_DATA_TYPE + "\" : \"" + sortDataType + "\"";
430 colOptions += " , \"" + UifConstants.TableToolsKeys.SORT_TYPE + "\" : \"" + sortType + "\"";
431 }
432
433 if (!colOptions.equals("null")) {
434 colOptions = "{" + colOptions + ", \"" + UifConstants.TableToolsKeys.TARGETS + "\": [" + target + "]}";
435 } else {
436 colOptions = "{" + colOptions + "}";
437 }
438
439 return colOptions;
440 }
441
442
443
444
445
446
447 @BeanTagAttribute(name = "emptyTableMessage")
448 public String getEmptyTableMessage() {
449 return emptyTableMessage;
450 }
451
452
453
454
455
456
457 public void setEmptyTableMessage(String emptyTableMessage) {
458 this.emptyTableMessage = emptyTableMessage;
459 }
460
461
462
463
464
465
466 @BeanTagAttribute(name = "disableTableSort")
467 public boolean isDisableTableSort() {
468 return this.disableTableSort;
469 }
470
471
472
473
474
475
476 public void setDisableTableSort(boolean disableTableSort) {
477 this.disableTableSort = disableTableSort;
478 }
479
480
481
482
483
484
485 @BeanTagAttribute(name = "showSearchAndExportOptions")
486 public boolean isShowSearchAndExportOptions() {
487 return this.showSearchAndExportOptions;
488 }
489
490
491
492
493
494
495 public void setShowSearchAndExportOptions(boolean showSearchAndExportOptions) {
496 this.showSearchAndExportOptions = showSearchAndExportOptions;
497 }
498
499
500
501
502
503
504
505
506 @BeanTagAttribute(name = "hiddenColumns", type = BeanTagAttribute.AttributeType.SETVALUE)
507 public Set<String> getHiddenColumns() {
508 return hiddenColumns;
509 }
510
511
512
513
514
515
516 public void setHiddenColumns(Set<String> hiddenColumns) {
517 this.hiddenColumns = hiddenColumns;
518 }
519
520
521
522
523
524
525
526
527 @BeanTagAttribute(name = "sortableColumns", type = BeanTagAttribute.AttributeType.SETVALUE)
528 public Set<String> getSortableColumns() {
529 return sortableColumns;
530 }
531
532
533
534
535
536
537 public void setSortableColumns(Set<String> sortableColumns) {
538 this.sortableColumns = sortableColumns;
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552 @BeanTagAttribute(name = "ajaxSource")
553 public String getAjaxSource() {
554 return ajaxSource;
555 }
556
557
558
559
560
561
562 public void setAjaxSource(String ajaxSource) {
563 this.ajaxSource = ajaxSource;
564 }
565
566
567
568
569
570
571 public String getGroupingOptionsJSString() {
572 return groupingOptionsJSString;
573 }
574
575
576
577
578
579
580 public void setGroupingOptionsJSString(String groupingOptionsJSString) {
581 this.groupingOptionsJSString = groupingOptionsJSString;
582 }
583
584 public boolean isForceAoColumnDefsOverride() {
585 return forceAoColumnDefsOverride;
586 }
587
588 public void setForceAoColumnDefsOverride(boolean forceAoColumnDefsOverride) {
589 this.forceAoColumnDefsOverride = forceAoColumnDefsOverride;
590 }
591 }