001/** 002 * Copyright 2005-2018 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 */ 016package org.kuali.rice.krad.uif.control; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import org.apache.commons.lang.StringUtils; 022import org.kuali.rice.krad.datadictionary.parse.BeanTag; 023import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 024import org.kuali.rice.krad.datadictionary.validator.ValidationTrace; 025import org.kuali.rice.krad.uif.UifConstants; 026import org.kuali.rice.krad.uif.component.Component; 027import org.kuali.rice.krad.uif.element.ContentElementBase; 028import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 029import org.kuali.rice.krad.uif.util.LifecycleElement; 030import org.kuali.rice.krad.uif.view.ExpressionEvaluator; 031import org.kuali.rice.krad.uif.view.View; 032 033/** 034 * Base class for all {@link Control} implementations. 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038@BeanTag(name = "controlBase", parent = "Uif-ControlBase") 039public abstract class ControlBase extends ContentElementBase implements Control { 040 private static final long serialVersionUID = -7898244978136312663L; 041 042 private int tabIndex; 043 044 private boolean disabled; 045 private String disabledExpression; 046 private String disabledReason; 047 private boolean evaluateDisabledOnKeyUp; 048 049 private String disabledConditionJs; 050 private List<String> disabledConditionControlNames; 051 052 private List<String> disabledWhenChangedPropertyNames; 053 private List<String> enabledWhenChangedPropertyNames; 054 055 public ControlBase() { 056 super(); 057 058 disabled = false; 059 disabledWhenChangedPropertyNames = new ArrayList<String>(); 060 enabledWhenChangedPropertyNames = new ArrayList<String>(); 061 } 062 063 /** 064 * Sets the disabledExpression, if any, evaluates it and sets the disabled property 065 * 066 * @param model top level object containing the data (could be the form or a 067 * top level business object, dto) 068 * @param parent 069 */ 070 @Override 071 public void performApplyModel(Object model, LifecycleElement parent) { 072 super.performApplyModel(model, parent); 073 074 disabledExpression = this.getPropertyExpression("disabled"); 075 if (disabledExpression != null) { 076 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator(); 077 078 disabledExpression = expressionEvaluator.replaceBindingPrefixes(ViewLifecycle.getView(), this, 079 disabledExpression); 080 disabled = (Boolean) expressionEvaluator.evaluateExpression(this.getContext(), disabledExpression); 081 } 082 } 083 084 /** 085 * Parses the disabled expressions, if any, to equivalent javascript and evaluates the disable/enable when 086 * changed property names. 087 * 088 * @param model top level object containing the data 089 * @param parent parent component 090 */ 091 @Override 092 public void performFinalize(Object model, LifecycleElement parent) { 093 super.performFinalize(model, parent); 094 095 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator(); 096 097 if (StringUtils.isNotEmpty(disabledExpression) 098 && !disabledExpression.equalsIgnoreCase("true") 099 && !disabledExpression.equalsIgnoreCase("false")) { 100 disabledConditionControlNames = new ArrayList<String>(); 101 disabledConditionJs = expressionEvaluator.parseExpression(disabledExpression, disabledConditionControlNames, 102 this.getContext()); 103 } 104 105 View view = ViewLifecycle.getView(); 106 List<String> adjustedDisablePropertyNames = new ArrayList<String>(); 107 for (String propertyName : disabledWhenChangedPropertyNames) { 108 adjustedDisablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this, propertyName)); 109 } 110 disabledWhenChangedPropertyNames = adjustedDisablePropertyNames; 111 112 List<String> adjustedEnablePropertyNames = new ArrayList<String>(); 113 for (String propertyName : enabledWhenChangedPropertyNames) { 114 adjustedEnablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this, propertyName)); 115 } 116 enabledWhenChangedPropertyNames = adjustedEnablePropertyNames; 117 118 // add control role 119 this.addDataAttribute(UifConstants.DataAttributes.ROLE, UifConstants.RoleTypes.CONTROL); 120 } 121 122 /** 123 * {@inheritDoc} 124 */ 125 @Override 126 public final String getComponentTypeName() { 127 return "control"; 128 } 129 130 /** 131 * {@inheritDoc} 132 */ 133 @BeanTagAttribute 134 public int getTabIndex() { 135 return this.tabIndex; 136 } 137 138 /** 139 * @see org.kuali.rice.krad.uif.control.Control#setTabIndex(int) 140 */ 141 public void setTabIndex(int tabIndex) { 142 this.tabIndex = tabIndex; 143 } 144 145 /** 146 * @see org.kuali.rice.krad.uif.control.Control#isDisabled() 147 */ 148 @BeanTagAttribute 149 public boolean isDisabled() { 150 return disabled; 151 } 152 153 /** 154 * @see org.kuali.rice.krad.uif.control.Control#setDisabled(boolean) 155 */ 156 public void setDisabled(boolean disabled) { 157 this.disabled = disabled; 158 } 159 160 /** 161 * @see org.kuali.rice.krad.uif.control.Control#getDisabledReason() 162 */ 163 @BeanTagAttribute 164 public String getDisabledReason() { 165 return disabledReason; 166 } 167 168 /** 169 * @see org.kuali.rice.krad.uif.control.Control#setDisabledReason(java.lang.String) 170 */ 171 public void setDisabledReason(String disabledReason) { 172 this.disabledReason = disabledReason; 173 } 174 175 /** 176 * Evaluate the disable condition on controls which disable it on each key up event 177 * 178 * @return true if evaluate on key up, false otherwise 179 */ 180 @BeanTagAttribute 181 public boolean isEvaluateDisabledOnKeyUp() { 182 return evaluateDisabledOnKeyUp; 183 } 184 185 /** 186 * Set evaluateDisableOnKeyUp 187 * 188 * @param evaluateDisabledOnKeyUp 189 */ 190 public void setEvaluateDisabledOnKeyUp(boolean evaluateDisabledOnKeyUp) { 191 this.evaluateDisabledOnKeyUp = evaluateDisabledOnKeyUp; 192 } 193 194 /** 195 * Get the disable condition js derived from the springEL, cannot be set. 196 * 197 * @return the disableConditionJs javascript to be evaluated 198 */ 199 public String getDisabledConditionJs() { 200 return disabledConditionJs; 201 } 202 203 /** 204 * Control names to add handlers to for disable functionality, cannot be set 205 * 206 * @return control names to add handlers to for disable 207 */ 208 public List<String> getDisabledConditionControlNames() { 209 return disabledConditionControlNames; 210 } 211 212 /** 213 * Gets the property names of fields that when changed, will disable this component 214 * 215 * @return the property names to monitor for change to disable this component 216 */ 217 @BeanTagAttribute 218 public List<String> getDisabledWhenChangedPropertyNames() { 219 return disabledWhenChangedPropertyNames; 220 } 221 222 /** 223 * Sets the property names of fields that when changed, will disable this component 224 * 225 * @param disabledWhenChangedPropertyNames 226 */ 227 public void setDisabledWhenChangedPropertyNames(List<String> disabledWhenChangedPropertyNames) { 228 this.disabledWhenChangedPropertyNames = disabledWhenChangedPropertyNames; 229 } 230 231 /** 232 * Gets the property names of fields that when changed, will enable this component 233 * 234 * @return the property names to monitor for change to enable this component 235 */ 236 @BeanTagAttribute 237 public List<String> getEnabledWhenChangedPropertyNames() { 238 return enabledWhenChangedPropertyNames; 239 } 240 241 /** 242 * Sets the property names of fields that when changed, will enable this component 243 * 244 * @param enabledWhenChangedPropertyNames 245 */ 246 public void setEnabledWhenChangedPropertyNames(List<String> enabledWhenChangedPropertyNames) { 247 this.enabledWhenChangedPropertyNames = enabledWhenChangedPropertyNames; 248 } 249 250 /** 251 * Sets the disabled expression 252 * 253 * @param disabledExpression 254 */ 255 protected void setDisabledExpression(String disabledExpression) { 256 this.disabledExpression = disabledExpression; 257 } 258 259 /** 260 * Sets the disabled condition javascript 261 * 262 * @param disabledConditionJs 263 */ 264 protected void setDisabledConditionJs(String disabledConditionJs) { 265 this.disabledConditionJs = disabledConditionJs; 266 } 267 268 /** 269 * Sets the disabled condition control names 270 * 271 * @param disabledConditionControlNames 272 */ 273 protected void setDisabledConditionControlNames(List<String> disabledConditionControlNames) { 274 this.disabledConditionControlNames = disabledConditionControlNames; 275 } 276 277 /** 278 * {@inheritDoc} 279 */ 280 @Override 281 public void completeValidation(ValidationTrace tracer) { 282 tracer.addBean(this); 283 284 super.completeValidation(tracer.getCopy()); 285 } 286}