1 24 package org.riotfamily.forms.element; 25 26 import java.beans.PropertyEditor ; 27 import java.io.PrintWriter ; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 32 import org.riotfamily.common.markup.Html; 33 import org.riotfamily.common.markup.TagWriter; 34 import org.riotfamily.common.util.PasswordGenerator; 35 import org.riotfamily.forms.AbstractEditorBase; 36 import org.riotfamily.forms.AbstractElement; 37 import org.riotfamily.forms.Editor; 38 import org.riotfamily.forms.ErrorUtils; 39 import org.riotfamily.forms.event.ChangeEvent; 40 import org.riotfamily.forms.event.ChangeListener; 41 import org.riotfamily.forms.event.JavaScriptEvent; 42 import org.riotfamily.forms.event.JavaScriptEventAdapter; 43 import org.riotfamily.forms.request.FormRequest; 44 import org.springframework.util.Assert; 45 import org.springframework.util.ObjectUtils; 46 import org.springframework.util.StringUtils; 47 48 49 56 public abstract class AbstractTextElement extends AbstractEditorBase 57 implements Editor , JavaScriptEventAdapter { 58 59 private String type = "text"; 60 61 private Integer maxLength; 62 63 private boolean trim = true; 64 65 private boolean randomParamName; 66 67 private List listeners; 68 69 private String text; 70 71 private Object value; 72 73 private PropertyEditor propertyEditor; 74 75 private boolean validateOnChange = false; 76 77 public AbstractTextElement() { 78 } 79 80 public AbstractTextElement(String type) { 81 this.type = type; 82 } 83 84 public String getType() { 85 return type; 86 } 87 88 public void setType(String type) { 89 this.type = type; 90 } 91 92 98 public String getStyleClass() { 99 String styleClass = super.getStyleClass(); 100 return styleClass != null ? styleClass : type; 101 } 102 103 public Integer getMaxLength() { 104 return this.maxLength; 105 } 106 107 110 public void setMaxLength(Integer maxLength) { 111 this.maxLength = maxLength; 112 } 113 114 117 public void setTrim(boolean trim) { 118 this.trim = trim; 119 } 120 121 125 public void setRandomParamName(boolean randomParamName) { 126 this.randomParamName = randomParamName; 128 } 129 130 134 public void setValidateOnChange(boolean validateOnChange) { 135 this.validateOnChange = validateOnChange; 136 } 137 138 public final void setPropertyEditor(PropertyEditor propertyEditor) { 139 this.propertyEditor = propertyEditor; 140 } 141 142 protected final PropertyEditor getPropertyEditor() { 143 return propertyEditor; 144 } 145 146 protected void initPropertyEditor() { 147 if (propertyEditor == null) { 148 this.propertyEditor = getEditorBinding().getPropertyEditor(); 149 } 150 } 151 152 protected void afterBindingSet() { 153 initPropertyEditor(); 154 } 155 156 public final String getText() { 157 return text; 158 } 159 160 164 public void setText(String text) { 165 if (trim && text != null) { 166 this.text = text.trim(); 167 } 168 else { 169 this.text = text; 170 } 171 } 172 173 public final Object getValue() { 174 return value; 175 } 176 177 public void setValue(Object value) { 178 this.value = value; 179 setTextFromValue(); 180 } 181 182 protected void setTextFromValue() { 183 if (value == null) { 184 text = null; 185 } 186 else if (value instanceof String ) { 187 text = (String ) value; 188 } 189 else { 190 if (propertyEditor == null) { 191 initPropertyEditor(); 192 Assert.notNull(propertyEditor, "Can't handle value of type " 193 + value.getClass().getName() + " - no PropertyEditor " 194 + "present"); 195 } 196 propertyEditor.setValue(value); 197 text = propertyEditor.getAsText(); 198 } 199 } 200 201 public void processRequest(FormRequest request) { 202 text = request.getParameter(getParamName()); 203 validate(true); 204 if (!ErrorUtils.hasErrors(this)) { 205 setValueFromText(); 206 } 207 } 208 209 public void handleJavaScriptEvent(JavaScriptEvent event) { 210 if (event.getType() == JavaScriptEvent.ON_CHANGE) { 211 text = event.getValue(); 212 ErrorUtils.removeErrors(this); 213 validate(false); 214 if (!ErrorUtils.hasErrors(this)) { 215 setValueFromText(); 216 } 217 } 218 } 219 220 protected void setValueFromText() { 221 Object oldValue = value; 222 if (!StringUtils.hasText(text)) { 223 value = null; 224 } 225 else { 226 if (propertyEditor != null) { 227 propertyEditor.setAsText(text); 228 value = propertyEditor.getValue(); 229 } 230 else { 231 value = text; 232 } 233 } 234 if (!ObjectUtils.nullSafeEquals(value, oldValue)) { 235 fireChangeEvent(value, oldValue); 236 } 237 } 238 239 protected void validate(boolean formSubmitted) { 240 if (isRequired() && !StringUtils.hasLength(text)) { 241 ErrorUtils.reject(this, "required"); 242 } 243 } 244 245 protected String getDesiredParamName() { 246 if (randomParamName) { 247 return PasswordGenerator.getDefaultInstance().generate(); 248 } 249 return super.getDesiredParamName(); 250 } 251 252 public void renderInternal(PrintWriter writer) { 253 TagWriter input = new TagWriter(writer); 254 input.startEmpty(Html.INPUT) 255 .attribute(Html.INPUT_TYPE, getType()) 256 .attribute(Html.COMMON_CLASS, getStyleClass()) 257 .attribute(Html.COMMON_ID, getId()) 258 .attribute(Html.INPUT_NAME, getParamName()) 259 .attribute(Html.INPUT_VALUE, getText()); 260 if (getMaxLength() != null) { 261 input.attribute(Html.INPUT_MAX_LENGTH, getMaxLength().intValue()); 262 } 263 input.end(); 264 } 265 266 public void addChangeListener(ChangeListener listener) { 267 if (listeners == null) { 268 listeners = new ArrayList (); 269 } 270 listeners.add(listener); 271 } 272 273 protected void fireChangeEvent(Object newValue, Object oldValue) { 274 if (listeners != null) { 275 ChangeEvent event = new ChangeEvent(this, newValue, oldValue); 276 Iterator it = listeners.iterator(); 277 while (it.hasNext()) { 278 ChangeListener listener = (ChangeListener) it.next(); 279 listener.valueChanged(event); 280 } 281 } 282 } 283 284 public int getEventTypes() { 285 if (validateOnChange || listeners != null) { 286 return JavaScriptEvent.ON_CHANGE; 287 } 288 return JavaScriptEvent.NONE; 289 } 290 291 } | Popular Tags |