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 }