View Javadoc
1   package org.kuali.rice.krad.uif.container.extension;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.kuali.rice.core.api.util.type.TypeUtils;
5   import org.kuali.rice.krad.uif.UifConstants;
6   import org.kuali.rice.krad.uif.field.DataFieldBase;
7   
8   import java.util.List;
9   
10  /**
11   * Addresses three issues
12   *
13   * 1. Supports DL/DD
14   * 2. Applies the styleClasses on the filed to the list container and provides a property to allow the list item value to be applied as a style also
15   * 3. Uses StringBuilder instead of String concatinations to improve memory usage
16   *
17   * @Author KSAP Team
18   * Date: 3/22/13
19   */
20  public class ListDataField extends DataFieldBase {
21  
22  
23      private static final String DL = "DL";
24  
25      private boolean applyCssOnItem = false;
26  
27      public boolean isApplyCssOnItem() {
28          return applyCssOnItem;
29      }
30  
31      public void setApplyCssOnItem(boolean applyCssOnItem) {
32          this.applyCssOnItem = applyCssOnItem;
33      }
34  
35      /**
36       * Besides the default list items, DD/DL is also now supported.
37       * The style classes are also not hard coded now and can be picked up from the dataFields styleClasses method
38       *
39       * @param list readonly list content to be displayed as a HTML definition list
40       * @return 
41       */
42      @Override
43      protected String generateReadOnlyListDisplayReplacement(List<?> list) {
44          StringBuilder generatedHtml = new StringBuilder();
45  
46          //Default to delimited if nothing is set
47          if (getReadOnlyListDisplayType() == null) {
48              this.setReadOnlyListDisplayType(UifConstants.ReadOnlyListTypes.DELIMITED.name());
49          }
50  
51          //begin generation setup
52          if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.UL.name())) {
53              generatedHtml.append("<ul class='uif-readOnlyStringList ").append(getStyleClassesAsString()).append("'>");
54          } else if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.OL.name())) {
55              generatedHtml.append("<ol class='uif-readOnlyStringList ").append(getStyleClassesAsString()).append("'>");
56          } else if (getReadOnlyListDisplayType().equalsIgnoreCase(DL)) {
57              generatedHtml.append("<dl class='uif-readOnlyStringList ").append(getStyleClassesAsString()).append("'>");
58          } else if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.BREAK.name())) {
59              setReadOnlyListDelimiter("<br/>");
60          } else if (this.getReadOnlyListDelimiter() == null) {
61              setReadOnlyListDelimiter(", ");
62          }
63  
64          //iterate through each value
65          for (Object value : list) {
66              //if blank skip
67              if (!TypeUtils.isSimpleType(value.getClass()) || StringUtils.isBlank(value.toString())) {
68                  continue;
69              }
70  
71              //handle mask if any
72              if (isApplyMask()) {
73                  value = getMaskFormatter().maskValue(value);
74              }
75  
76  
77              // TODO KSAP-740: Investigate using something similar to CrudMessageMatrixFormatter style tag generation
78              // As well as a string formatter
79              // the value should use the formatted text property value we would expect to see instead of toString
80              //two types - delimited and html list
81              if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.UL.name())
82                      || getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.OL.name())) {
83                  generatedHtml.append("<li");
84                  if(applyCssOnItem) generatedHtml.append(" '").append(value.toString()).append("'");
85                  generatedHtml.append(">").append(value.toString()).append("</li>");
86              } else if (getReadOnlyListDisplayType().equalsIgnoreCase(DL)) {
87                  generatedHtml.append("<dd");
88                  if(applyCssOnItem) generatedHtml.append(" '").append(value.toString()).append("'");
89                  generatedHtml.append(">").append(value.toString()).append("</dd>");
90              } else {
91                  //no matching needed - delimited is always the fallback and break uses same logic
92                  generatedHtml.append(value.toString()).append(this.getReadOnlyListDelimiter());
93              }
94          }
95  
96          //end the generation
97          if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.UL.name())) {
98              generatedHtml.append("</ul>");
99          } else if (getReadOnlyListDisplayType().equalsIgnoreCase(UifConstants.ReadOnlyListTypes.OL.name())) {
100             generatedHtml.append("</ol>");
101         } else if (getReadOnlyListDisplayType().equalsIgnoreCase(DL)) {
102             generatedHtml.append("</dl>");
103         }else {
104             generatedHtml.delete(generatedHtml.length() - this.getReadOnlyListDelimiter().length(), generatedHtml.length() );
105         }
106 
107         if (generatedHtml.length() > 0) {
108             this.setReadOnlyDisplayReplacement(generatedHtml.toString());
109         } else {
110             //this must be done or the ftl will skip and throw error
111             this.setReadOnlyDisplayReplacement("&nbsp;");
112         }
113         return getReadOnlyDisplayReplacement();
114     }
115 }