View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.control;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21  import org.kuali.rice.krad.datadictionary.validator.ErrorReport;
22  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
24  import org.kuali.rice.krad.uif.component.Component;
25  import org.kuali.rice.krad.uif.element.ContentElementBase;
26  import org.kuali.rice.krad.uif.service.ExpressionEvaluatorService;
27  import org.kuali.rice.krad.uif.util.ExpressionUtils;
28  import org.kuali.rice.krad.uif.view.View;
29  
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  /**
34   * Base class for all <code>Control</code> implementations
35   *
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   * @see org.kuali.rice.krad.uif.control.Control
38   */
39  @BeanTag(name = "controlBase-bean", parent = "Uif-ControlBase")
40  public abstract class ControlBase extends ContentElementBase implements Control {
41      private static final long serialVersionUID = -7898244978136312663L;
42  
43      private int tabIndex;
44  
45      private boolean disabled;
46      private String disabledExpression;
47      private String disabledReason;
48      private boolean evaluateDisabledOnKeyUp;
49  
50      private String disabledConditionJs;
51      private List<String> disabledConditionControlNames;
52  
53      private List<String> disabledWhenChangedPropertyNames;
54      private List<String> enabledWhenChangedPropertyNames;
55  
56      public ControlBase() {
57          super();
58  
59          disabled = false;
60          disabledWhenChangedPropertyNames = new ArrayList<String>();
61          enabledWhenChangedPropertyNames = new ArrayList<String>();
62      }
63  
64      /**
65       * Sets the disabledExpression, if any, evaluates it and sets the disabled property
66       *
67       * @param view - view instance to which the component belongs
68       * @param model - Top level object containing the data (could be the form or a
69       * @param parent
70       */
71      public void performApplyModel(View view, Object model, Component parent) {
72          super.performApplyModel(view, model, parent);
73  
74          disabledExpression = this.getPropertyExpression("disabled");
75          if(disabledExpression != null){
76              ExpressionEvaluatorService expressionEvaluatorService =
77                                  KRADServiceLocatorWeb.getExpressionEvaluatorService();
78              disabledExpression = expressionEvaluatorService.replaceBindingPrefixes(view, this,
79                      disabledExpression);
80              disabled = (Boolean) expressionEvaluatorService.evaluateExpression(model, this.getContext(),
81                      disabledExpression);
82          }
83      }
84  
85      /**
86       * Parses the disabled expressions, if any, to equivalent javascript and evaluates the disable/enable when
87       * changed property names.
88       *
89       * @param view - view instance that should be finalized for rendering
90       * @param model - top level object containing the data
91       * @param parent - parent component
92       */
93      public void performFinalize(View view, Object model, Component parent) {
94          super.performApplyModel(view, model, parent);
95  
96          if (StringUtils.isNotEmpty(disabledExpression) && !disabledExpression.equalsIgnoreCase("true")
97                  && !disabledExpression.equalsIgnoreCase("false")) {
98              disabledConditionControlNames = new ArrayList<String>();
99              disabledConditionJs = ExpressionUtils.parseExpression(disabledExpression,
100                     disabledConditionControlNames);
101         }
102 
103         List<String> adjustedDisablePropertyNames = new ArrayList<String>();
104         for (String propertyName : disabledWhenChangedPropertyNames) {
105             adjustedDisablePropertyNames.add(
106                     KRADServiceLocatorWeb.getExpressionEvaluatorService().replaceBindingPrefixes(view, this,
107                             propertyName));
108         }
109         disabledWhenChangedPropertyNames = adjustedDisablePropertyNames;
110 
111         List<String> adjustedEnablePropertyNames = new ArrayList<String>();
112         for (String propertyName : enabledWhenChangedPropertyNames) {
113             adjustedEnablePropertyNames.add(
114                     KRADServiceLocatorWeb.getExpressionEvaluatorService().replaceBindingPrefixes(view, this,
115                             propertyName));
116         }
117         enabledWhenChangedPropertyNames = adjustedEnablePropertyNames;
118     }
119 
120     /**
121      * @see org.kuali.rice.krad.uif.component.Component#getComponentTypeName()
122      */
123     @Override
124     public final String getComponentTypeName() {
125         return "control";
126     }
127 
128     /**
129      * @see org.kuali.rice.krad.uif.control.Control#getTabIndex()
130      */
131     @BeanTagAttribute(name="tabIndex")
132     public int getTabIndex() {
133         return this.tabIndex;
134     }
135 
136     /**
137      * @see org.kuali.rice.krad.uif.control.Control#setTabIndex(int)
138      */
139     public void setTabIndex(int tabIndex) {
140         this.tabIndex = tabIndex;
141     }
142 
143     /**
144      * @see org.kuali.rice.krad.uif.control.Control#isDisabled()
145      */
146     @BeanTagAttribute(name="disabled")
147     public boolean isDisabled() {
148         return disabled;
149     }
150 
151     /**
152      * @see org.kuali.rice.krad.uif.control.Control#setDisabled(boolean)
153      */
154     public void setDisabled(boolean disabled) {
155         this.disabled = disabled;
156     }
157 
158     /**
159      * @see org.kuali.rice.krad.uif.control.Control#getDisabledReason()
160      */
161     @BeanTagAttribute(name="disabledReason")
162     public String getDisabledReason() {
163         return disabledReason;
164     }
165 
166     /**
167      * @see org.kuali.rice.krad.uif.control.Control#setDisabledReason(java.lang.String)
168      */
169     public void setDisabledReason(String disabledReason) {
170         this.disabledReason = disabledReason;
171     }
172 
173     /**
174      * Returns js that will add data to this component by the element which matches its id.
175      *
176      * <p> This will return script for all the data elements since this component is implemented as a spring form:input
177      * tag
178      * that does not allow for the insertion of simple attributes. Therefore, the complex attributes script should
179      * include
180      * all the attributes since is it is inserted each time krad:template is used to display a control</p>
181      *
182      * @return jQuery data script for all data attributes
183      */
184     @Override
185     public String getComplexDataAttributesJs() {
186         /*TODO find out if all controls will need to override this. If not, uncomment and add the ones that need to the array
187         // classes which will exhibit the overriding behaviour
188         Class[] allowedcontrols = {TextAreaControl.class, TextControl.class, FileControl.class};
189         for (Class klass: allowedcontrols) {
190             if (klass.isAssignableFrom(this.getClass())) {
191                 return super.getAllDataAttributesJs();
192             }
193         }
194         return super.getComplexDataAttributesJs();*/
195         return super.getAllDataAttributesJs();
196     }
197 
198     /**
199      * @see org.kuali.rice.krad.uif.component.Component#completeValidation
200      */
201     @Override
202     public void completeValidation(ValidationTrace tracer){
203         tracer.addBean(this);
204 
205         super.completeValidation(tracer.getCopy());
206     }
207 
208 
209     /**
210      * Evaluate the disable condition on controls which disable it on each key up event
211      *
212      * @return true if evaluate on key up, false otherwise
213      */
214     @BeanTagAttribute(name="evaluateDisabledOnKeyUp")
215     public boolean isEvaluateDisabledOnKeyUp() {
216         return evaluateDisabledOnKeyUp;
217     }
218 
219     /**
220      * Set evaluateDisableOnKeyUp
221      *
222      * @param evaluateDisabledOnKeyUp
223      */
224     public void setEvaluateDisabledOnKeyUp(boolean evaluateDisabledOnKeyUp) {
225         this.evaluateDisabledOnKeyUp = evaluateDisabledOnKeyUp;
226     }
227 
228     /**
229      * Get the disable condition js derived from the springEL, cannot be set.
230      *
231      * @return the disableConditionJs javascript to be evaluated
232      */
233     public String getDisabledConditionJs() {
234         return disabledConditionJs;
235     }
236 
237     /**
238      * Control names to add handlers to for disable functionality, cannot be set
239      *
240      * @return control names to add handlers to for disable
241      */
242     public List<String> getDisabledConditionControlNames() {
243         return disabledConditionControlNames;
244     }
245 
246     /**
247      * Gets the property names of fields that when changed, will disable this component
248      *
249      * @return the property names to monitor for change to disable this component
250      */
251     @BeanTagAttribute(name="disabledWhenChangedPropertyNames",type= BeanTagAttribute.AttributeType.LISTVALUE)
252     public List<String> getDisabledWhenChangedPropertyNames() {
253         return disabledWhenChangedPropertyNames;
254     }
255 
256     /**
257      * Sets the property names of fields that when changed, will disable this component
258      *
259      * @param disabledWhenChangedPropertyNames
260      */
261     public void setDisabledWhenChangedPropertyNames(List<String> disabledWhenChangedPropertyNames) {
262         this.disabledWhenChangedPropertyNames = disabledWhenChangedPropertyNames;
263     }
264 
265     /**
266      * Gets the property names of fields that when changed, will enable this component
267      *
268      * @return the property names to monitor for change to enable this component
269      */
270     @BeanTagAttribute(name="ensabledConditionControlNames",type= BeanTagAttribute.AttributeType.LISTVALUE)
271     public List<String> getEnabledWhenChangedPropertyNames() {
272         return enabledWhenChangedPropertyNames;
273     }
274 
275     /**
276      * Sets the property names of fields that when changed, will enable this component
277      *
278      * @param enabledWhenChangedPropertyNames
279      */
280     public void setEnabledWhenChangedPropertyNames(List<String> enabledWhenChangedPropertyNames) {
281         this.enabledWhenChangedPropertyNames = enabledWhenChangedPropertyNames;
282     }
283 }