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