001 /**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krad.uif.control;
017
018 import com.google.common.collect.Lists;
019 import org.apache.commons.lang.StringUtils;
020 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
021 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
022 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
023 import org.kuali.rice.krad.uif.UifConstants;
024 import org.kuali.rice.krad.uif.component.Component;
025 import org.kuali.rice.krad.uif.element.ContentElementBase;
026 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
027 import org.kuali.rice.krad.uif.util.ExpressionUtils;
028 import org.kuali.rice.krad.uif.view.View;
029
030 import java.util.ArrayList;
031 import java.util.List;
032
033 /**
034 * Base class for all <code>Control</code> implementations
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 * @see org.kuali.rice.krad.uif.control.Control
038 */
039 @BeanTag(name = "controlBase-bean", parent = "Uif-ControlBase")
040 public abstract class ControlBase extends ContentElementBase implements Control {
041 private static final long serialVersionUID = -7898244978136312663L;
042
043 private int tabIndex;
044
045 private boolean disabled;
046 private String disabledExpression;
047 private String disabledReason;
048 private boolean evaluateDisabledOnKeyUp;
049
050 private String disabledConditionJs;
051 private List<String> disabledConditionControlNames;
052
053 private List<String> disabledWhenChangedPropertyNames;
054 private List<String> enabledWhenChangedPropertyNames;
055
056 public ControlBase() {
057 super();
058
059 disabled = false;
060 disabledWhenChangedPropertyNames = new ArrayList<String>();
061 enabledWhenChangedPropertyNames = new ArrayList<String>();
062 }
063
064 /**
065 * Sets the disabledExpression, if any, evaluates it and sets the disabled property
066 *
067 * @param view view instance to which the component belongs
068 * @param model top level object containing the data (could be the form or a
069 * top level business object, dto)
070 * @param parent
071 */
072 public void performApplyModel(View view, Object model, Component parent) {
073 super.performApplyModel(view, model, parent);
074
075 disabledExpression = this.getPropertyExpression("disabled");
076 if(disabledExpression != null){
077 ExpressionEvaluator expressionEvaluator =
078 view.getViewHelperService().getExpressionEvaluator();
079
080 disabledExpression = expressionEvaluator.replaceBindingPrefixes(view, this,
081 disabledExpression);
082 disabled = (Boolean) expressionEvaluator.evaluateExpression(this.getContext(), disabledExpression);
083 }
084 }
085
086 /**
087 * Parses the disabled expressions, if any, to equivalent javascript and evaluates the disable/enable when
088 * changed property names.
089 *
090 * @param view view instance that should be finalized for rendering
091 * @param model top level object containing the data
092 * @param parent parent component
093 */
094 public void performFinalize(View view, Object model, Component parent) {
095 super.performApplyModel(view, model, parent);
096
097 ExpressionEvaluator expressionEvaluator =
098 view.getViewHelperService().getExpressionEvaluator();
099
100 if (StringUtils.isNotEmpty(disabledExpression) && !disabledExpression.equalsIgnoreCase("true")
101 && !disabledExpression.equalsIgnoreCase("false")) {
102 disabledConditionControlNames = new ArrayList<String>();
103 disabledConditionJs = ExpressionUtils.parseExpression(disabledExpression,
104 disabledConditionControlNames);
105 }
106
107 List<String> adjustedDisablePropertyNames = new ArrayList<String>();
108 for (String propertyName : disabledWhenChangedPropertyNames) {
109 adjustedDisablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this,
110 propertyName));
111 }
112 disabledWhenChangedPropertyNames = adjustedDisablePropertyNames;
113
114 List<String> adjustedEnablePropertyNames = new ArrayList<String>();
115 for (String propertyName : enabledWhenChangedPropertyNames) {
116 adjustedEnablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this,
117 propertyName));
118 }
119 enabledWhenChangedPropertyNames = adjustedEnablePropertyNames;
120
121 // add control role
122 this.addDataAttribute(UifConstants.DataAttributes.ROLE, UifConstants.RoleTypes.CONTROL);
123 }
124
125 /**
126 * @see org.kuali.rice.krad.uif.component.Component#getComponentTypeName()
127 */
128 @Override
129 public final String getComponentTypeName() {
130 return "control";
131 }
132
133 /**
134 * @see org.kuali.rice.krad.uif.control.Control#getTabIndex()
135 */
136 @BeanTagAttribute(name="tabIndex")
137 public int getTabIndex() {
138 return this.tabIndex;
139 }
140
141 /**
142 * @see org.kuali.rice.krad.uif.control.Control#setTabIndex(int)
143 */
144 public void setTabIndex(int tabIndex) {
145 this.tabIndex = tabIndex;
146 }
147
148 /**
149 * @see org.kuali.rice.krad.uif.control.Control#isDisabled()
150 */
151 @BeanTagAttribute(name="disabled")
152 public boolean isDisabled() {
153 return disabled;
154 }
155
156 /**
157 * @see org.kuali.rice.krad.uif.control.Control#setDisabled(boolean)
158 */
159 public void setDisabled(boolean disabled) {
160 this.disabled = disabled;
161 }
162
163 /**
164 * @see org.kuali.rice.krad.uif.control.Control#getDisabledReason()
165 */
166 @BeanTagAttribute(name="disabledReason")
167 public String getDisabledReason() {
168 return disabledReason;
169 }
170
171 /**
172 * @see org.kuali.rice.krad.uif.control.Control#setDisabledReason(java.lang.String)
173 */
174 public void setDisabledReason(String disabledReason) {
175 this.disabledReason = disabledReason;
176 }
177
178 /**
179 * @see org.kuali.rice.krad.uif.component.Component#completeValidation
180 */
181 @Override
182 public void completeValidation(ValidationTrace tracer){
183 tracer.addBean(this);
184
185 super.completeValidation(tracer.getCopy());
186 }
187
188
189 /**
190 * Evaluate the disable condition on controls which disable it on each key up event
191 *
192 * @return true if evaluate on key up, false otherwise
193 */
194 @BeanTagAttribute(name="evaluateDisabledOnKeyUp")
195 public boolean isEvaluateDisabledOnKeyUp() {
196 return evaluateDisabledOnKeyUp;
197 }
198
199 /**
200 * Set evaluateDisableOnKeyUp
201 *
202 * @param evaluateDisabledOnKeyUp
203 */
204 public void setEvaluateDisabledOnKeyUp(boolean evaluateDisabledOnKeyUp) {
205 this.evaluateDisabledOnKeyUp = evaluateDisabledOnKeyUp;
206 }
207
208 /**
209 * Get the disable condition js derived from the springEL, cannot be set.
210 *
211 * @return the disableConditionJs javascript to be evaluated
212 */
213 public String getDisabledConditionJs() {
214 return disabledConditionJs;
215 }
216
217 /**
218 * Control names to add handlers to for disable functionality, cannot be set
219 *
220 * @return control names to add handlers to for disable
221 */
222 public List<String> getDisabledConditionControlNames() {
223 return disabledConditionControlNames;
224 }
225
226 /**
227 * Gets the property names of fields that when changed, will disable this component
228 *
229 * @return the property names to monitor for change to disable this component
230 */
231 @BeanTagAttribute(name="disabledWhenChangedPropertyNames",type= BeanTagAttribute.AttributeType.LISTVALUE)
232 public List<String> getDisabledWhenChangedPropertyNames() {
233 return disabledWhenChangedPropertyNames;
234 }
235
236 /**
237 * Sets the property names of fields that when changed, will disable this component
238 *
239 * @param disabledWhenChangedPropertyNames
240 */
241 public void setDisabledWhenChangedPropertyNames(List<String> disabledWhenChangedPropertyNames) {
242 this.disabledWhenChangedPropertyNames = disabledWhenChangedPropertyNames;
243 }
244
245 /**
246 * Gets the property names of fields that when changed, will enable this component
247 *
248 * @return the property names to monitor for change to enable this component
249 */
250 @BeanTagAttribute(name="ensabledConditionControlNames",type= BeanTagAttribute.AttributeType.LISTVALUE)
251 public List<String> getEnabledWhenChangedPropertyNames() {
252 return enabledWhenChangedPropertyNames;
253 }
254
255 /**
256 * Sets the property names of fields that when changed, will enable this component
257 *
258 * @param enabledWhenChangedPropertyNames
259 */
260 public void setEnabledWhenChangedPropertyNames(List<String> enabledWhenChangedPropertyNames) {
261 this.enabledWhenChangedPropertyNames = enabledWhenChangedPropertyNames;
262 }
263
264 public void setDisabledExpression(String disabledExpression) {
265 this.disabledExpression = disabledExpression;
266 }
267
268 public String getDisabledExpression() {
269 return disabledExpression;
270 }
271
272 public void setDisabledConditionJs(String disabledConditionJs) {
273 this.disabledConditionJs = disabledConditionJs;
274 }
275
276 public void setDisabledConditionControlNames(List<String> disabledConditionControlNames) {
277 this.disabledConditionControlNames = disabledConditionControlNames;
278 }
279
280 /**
281 * @see org.kuali.rice.krad.uif.component.ComponentBase#copy()
282 */
283 @Override
284 protected <T> void copyProperties(T component) {
285 super.copyProperties(component);
286 ControlBase controlBaseCopy = (ControlBase) component;
287 controlBaseCopy.setTabIndex(this.getTabIndex());
288 controlBaseCopy.setDisabled(this.isDisabled());
289 controlBaseCopy.setDisabledExpression(this.getDisabledExpression());
290 controlBaseCopy.setDisabledReason(this.getDisabledReason());
291 controlBaseCopy.setEvaluateDisabledOnKeyUp(this.isEvaluateDisabledOnKeyUp());
292 controlBaseCopy.setDisabledConditionJs(this.getDisabledConditionJs());
293
294 if (disabledConditionControlNames != null) {
295 List<String> disabledConditionControlNamesCopy = Lists.newArrayListWithExpectedSize(
296 disabledConditionControlNames.size());
297
298 for(String disabledConditionControlName : disabledConditionControlNames) {
299 disabledConditionControlNamesCopy.add(disabledConditionControlName);
300 }
301
302 controlBaseCopy.setDisabledConditionControlNames(disabledConditionControlNamesCopy);
303 }
304
305 if (disabledWhenChangedPropertyNames != null) {
306 List<String> disabledWhenChangedPropertyNamesCopy = Lists.newArrayListWithExpectedSize(disabledWhenChangedPropertyNames.size());
307
308 for(String disabledWhenChangedPropertyName : disabledWhenChangedPropertyNames) {
309 disabledWhenChangedPropertyNamesCopy.add(disabledWhenChangedPropertyName);
310 }
311
312 controlBaseCopy.setDisabledWhenChangedPropertyNames(disabledWhenChangedPropertyNamesCopy);
313 }
314
315 if (enabledWhenChangedPropertyNames != null) {
316 List<String> enabledWhenChangedPropertyNamesCopy = Lists.newArrayListWithExpectedSize(enabledWhenChangedPropertyNames.size());
317
318 for(String enabledWhenChangedPropertyName : enabledWhenChangedPropertyNames) {
319 enabledWhenChangedPropertyNamesCopy.add(enabledWhenChangedPropertyName);
320 }
321
322 controlBaseCopy.setEnabledWhenChangedPropertyNames(enabledWhenChangedPropertyNamesCopy);
323 }
324 }
325 }