001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache 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 * https://www.apache.org/licenses/LICENSE-2.0 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 017package org.springframework.web.servlet.tags.form; 018 019import java.util.Map; 020 021import javax.servlet.jsp.JspException; 022 023import org.springframework.lang.Nullable; 024 025/** 026 * The {@code <input>} tag renders an HTML 'input' tag with type 'text' using 027 * the bound value. 028 * 029 * <p> 030 * <table> 031 * <caption>Attribute Summary</caption> 032 * <thead> 033 * <tr> 034 * <th class="colFirst">Attribute</th> 035 * <th class="colOne">Required?</th> 036 * <th class="colOne">Runtime Expression?</th> 037 * <th class="colLast">Description</th> 038 * </tr> 039 * </thead> 040 * <tbody> 041 * <tr class="altColor"> 042 * <td><p>accesskey</p></td> 043 * <td><p>false</p></td> 044 * <td><p>true</p></td> 045 * <td><p>HTML Standard Attribute</p></td> 046 * </tr> 047 * <tr class="rowColor"> 048 * <td><p>alt</p></td> 049 * <td><p>false</p></td> 050 * <td><p>true</p></td> 051 * <td><p>HTML Optional Attribute</p></td> 052 * </tr> 053 * <tr class="altColor"> 054 * <td><p>autocomplete</p></td> 055 * <td><p>false</p></td> 056 * <td><p>true</p></td> 057 * <td><p>Common Optional Attribute</p></td> 058 * </tr> 059 * <tr class="rowColor"> 060 * <td><p>cssClass</p></td> 061 * <td><p>false</p></td> 062 * <td><p>true</p></td> 063 * <td><p>HTML Optional Attribute</p></td> 064 * </tr> 065 * <tr class="altColor"> 066 * <td><p>cssErrorClass</p></td> 067 * <td><p>false</p></td> 068 * <td><p>true</p></td> 069 * <td><p>HTML Optional Attribute. Used when the bound field has errors.</p></td> 070 * </tr> 071 * <tr class="rowColor"> 072 * <td><p>cssStyle</p></td> 073 * <td><p>false</p></td> 074 * <td><p>true</p></td> 075 * <td><p>HTML Optional Attribute</p></td> 076 * </tr> 077 * <tr class="altColor"> 078 * <td><p>dir</p></td> 079 * <td><p>false</p></td> 080 * <td><p>true</p></td> 081 * <td><p>HTML Standard Attribute</p></td> 082 * </tr> 083 * <tr class="rowColor"> 084 * <td><p>disabled</p></td> 085 * <td><p>false</p></td> 086 * <td><p>true</p></td> 087 * <td><p>HTML Optional Attribute. Setting the value of this attribute to 088 * 'true' will disable the HTML element.</p></td> 089 * </tr> 090 * <tr class="altColor"> 091 * <td><p>htmlEscape</p></td> 092 * <td><p>false</p></td> 093 * <td><p>true</p></td> 094 * <td><p>Enable/disable HTML escaping of rendered values.</p></td> 095 * </tr> 096 * <tr class="rowColor"> 097 * <td><p>id</p></td> 098 * <td><p>false</p></td> 099 * <td><p>true</p></td> 100 * <td><p>HTML Standard Attribute</p></td> 101 * </tr> 102 * <tr class="altColor"> 103 * <td><p>lang</p></td> 104 * <td><p>false</p></td> 105 * <td><p>true</p></td> 106 * <td><p>HTML Standard Attribute</p></td> 107 * </tr> 108 * <tr class="rowColor"> 109 * <td><p>maxlength</p></td> 110 * <td><p>false</p></td> 111 * <td><p>true</p></td> 112 * <td><p>HTML Optional Attribute</p></td> 113 * </tr> 114 * <tr class="altColor"> 115 * <td><p>onblur</p></td> 116 * <td><p>false</p></td> 117 * <td><p>true</p></td> 118 * <td><p>HTML Event Attribute</p></td> 119 * </tr> 120 * <tr class="rowColor"> 121 * <td><p>onchange</p></td> 122 * <td><p>false</p></td> 123 * <td><p>true</p></td> 124 * <td><p>HTML Event Attribute</p></td> 125 * </tr> 126 * <tr class="altColor"> 127 * <td><p>onclick</p></td> 128 * <td><p>false</p></td> 129 * <td><p>true</p></td> 130 * <td><p>HTML Event Attribute</p></td> 131 * </tr> 132 * <tr class="rowColor"> 133 * <td><p>ondblclick</p></td> 134 * <td><p>false</p></td> 135 * <td><p>true</p></td> 136 * <td><p>HTML Event Attribute</p></td> 137 * </tr> 138 * <tr class="altColor"> 139 * <td><p>onfocus</p></td> 140 * <td><p>false</p></td> 141 * <td><p>true</p></td> 142 * <td><p>HTML Event Attribute</p></td> 143 * </tr> 144 * <tr class="rowColor"> 145 * <td><p>onkeydown</p></td> 146 * <td><p>false</p></td> 147 * <td><p>true</p></td> 148 * <td><p>HTML Event Attribute</p></td> 149 * </tr> 150 * <tr class="altColor"> 151 * <td><p>onkeypress</p></td> 152 * <td><p>false</p></td> 153 * <td><p>true</p></td> 154 * <td><p>HTML Event Attribute</p></td> 155 * </tr> 156 * <tr class="rowColor"> 157 * <td><p>onkeyup</p></td> 158 * <td><p>false</p></td> 159 * <td><p>true</p></td> 160 * <td><p>HTML Event Attribute</p></td> 161 * </tr> 162 * <tr class="altColor"> 163 * <td><p>onmousedown</p></td> 164 * <td><p>false</p></td> 165 * <td><p>true</p></td> 166 * <td><p>HTML Event Attribute</p></td> 167 * </tr> 168 * <tr class="rowColor"> 169 * <td><p>onmousemove</p></td> 170 * <td><p>false</p></td> 171 * <td><p>true</p></td> 172 * <td><p>HTML Event Attribute</p></td> 173 * </tr> 174 * <tr class="altColor"> 175 * <td><p>onmouseout</p></td> 176 * <td><p>false</p></td> 177 * <td><p>true</p></td> 178 * <td><p>HTML Event Attribute</p></td> 179 * </tr> 180 * <tr class="rowColor"> 181 * <td><p>onmouseover</p></td> 182 * <td><p>false</p></td> 183 * <td><p>true</p></td> 184 * <td><p>HTML Event Attribute</p></td> 185 * </tr> 186 * <tr class="altColor"> 187 * <td><p>onmouseup</p></td> 188 * <td><p>false</p></td> 189 * <td><p>true</p></td> 190 * <td><p>HTML Event Attribute</p></td> 191 * </tr> 192 * <tr class="rowColor"> 193 * <td><p>onselect</p></td> 194 * <td><p>false</p></td> 195 * <td><p>true</p></td> 196 * <td><p>HTML Event Attribute</p></td> 197 * </tr> 198 * <tr class="altColor"> 199 * <td><p>path</p></td> 200 * <td><p>true</p></td> 201 * <td><p>true</p></td> 202 * <td><p>Path to property for data binding</p></td> 203 * </tr> 204 * <tr class="rowColor"> 205 * <td><p>readonly</p></td> 206 * <td><p>false</p></td> 207 * <td><p>true</p></td> 208 * <td><p>HTML Optional Attribute. Setting the value of this attribute to 209 * 'true' will make the HTML element readonly.</p></td> 210 * </tr> 211 * <tr class="altColor"> 212 * <td><p>size</p></td> 213 * <td><p>false</p></td> 214 * <td><p>true</p></td> 215 * <td><p>HTML Optional Attribute</p></td> 216 * </tr> 217 * <tr class="rowColor"> 218 * <td><p>tabindex</p></td> 219 * <td><p>false</p></td> 220 * <td><p>true</p></td> 221 * <td><p>HTML Standard Attribute</p></td> 222 * </tr> 223 * <tr class="altColor"> 224 * <td><p>title</p></td> 225 * <td><p>false</p></td> 226 * <td><p>true</p></td> 227 * <td><p>HTML Standard Attribute</p></td> 228 * </tr> 229 * </tbody> 230 * </table> 231 * 232 * @author Rob Harrop 233 * @author Juergen Hoeller 234 * @author Rossen Stoyanchev 235 * @since 2.0 236 */ 237@SuppressWarnings("serial") 238public class InputTag extends AbstractHtmlInputElementTag { 239 240 public static final String SIZE_ATTRIBUTE = "size"; 241 242 public static final String MAXLENGTH_ATTRIBUTE = "maxlength"; 243 244 public static final String ALT_ATTRIBUTE = "alt"; 245 246 public static final String ONSELECT_ATTRIBUTE = "onselect"; 247 248 public static final String AUTOCOMPLETE_ATTRIBUTE = "autocomplete"; 249 250 251 @Nullable 252 private String size; 253 254 @Nullable 255 private String maxlength; 256 257 @Nullable 258 private String alt; 259 260 @Nullable 261 private String onselect; 262 263 @Nullable 264 private String autocomplete; 265 266 267 /** 268 * Set the value of the '{@code size}' attribute. 269 * May be a runtime expression. 270 */ 271 public void setSize(String size) { 272 this.size = size; 273 } 274 275 /** 276 * Get the value of the '{@code size}' attribute. 277 */ 278 @Nullable 279 protected String getSize() { 280 return this.size; 281 } 282 283 /** 284 * Set the value of the '{@code maxlength}' attribute. 285 * May be a runtime expression. 286 */ 287 public void setMaxlength(String maxlength) { 288 this.maxlength = maxlength; 289 } 290 291 /** 292 * Get the value of the '{@code maxlength}' attribute. 293 */ 294 @Nullable 295 protected String getMaxlength() { 296 return this.maxlength; 297 } 298 299 /** 300 * Set the value of the '{@code alt}' attribute. 301 * May be a runtime expression. 302 */ 303 public void setAlt(String alt) { 304 this.alt = alt; 305 } 306 307 /** 308 * Get the value of the '{@code alt}' attribute. 309 */ 310 @Nullable 311 protected String getAlt() { 312 return this.alt; 313 } 314 315 /** 316 * Set the value of the '{@code onselect}' attribute. 317 * May be a runtime expression. 318 */ 319 public void setOnselect(String onselect) { 320 this.onselect = onselect; 321 } 322 323 /** 324 * Get the value of the '{@code onselect}' attribute. 325 */ 326 @Nullable 327 protected String getOnselect() { 328 return this.onselect; 329 } 330 331 /** 332 * Set the value of the '{@code autocomplete}' attribute. 333 * May be a runtime expression. 334 */ 335 public void setAutocomplete(String autocomplete) { 336 this.autocomplete = autocomplete; 337 } 338 339 /** 340 * Get the value of the '{@code autocomplete}' attribute. 341 */ 342 @Nullable 343 protected String getAutocomplete() { 344 return this.autocomplete; 345 } 346 347 348 /** 349 * Writes the '{@code input}' tag to the supplied {@link TagWriter}. 350 * Uses the value returned by {@link #getType()} to determine which 351 * type of '{@code input}' element to render. 352 */ 353 @Override 354 protected int writeTagContent(TagWriter tagWriter) throws JspException { 355 tagWriter.startTag("input"); 356 357 writeDefaultAttributes(tagWriter); 358 Map<String, Object> attributes = getDynamicAttributes(); 359 if (attributes == null || !attributes.containsKey("type")) { 360 tagWriter.writeAttribute("type", getType()); 361 } 362 writeValue(tagWriter); 363 364 // custom optional attributes 365 writeOptionalAttribute(tagWriter, SIZE_ATTRIBUTE, getSize()); 366 writeOptionalAttribute(tagWriter, MAXLENGTH_ATTRIBUTE, getMaxlength()); 367 writeOptionalAttribute(tagWriter, ALT_ATTRIBUTE, getAlt()); 368 writeOptionalAttribute(tagWriter, ONSELECT_ATTRIBUTE, getOnselect()); 369 writeOptionalAttribute(tagWriter, AUTOCOMPLETE_ATTRIBUTE, getAutocomplete()); 370 371 tagWriter.endTag(); 372 return SKIP_BODY; 373 } 374 375 /** 376 * Writes the '{@code value}' attribute to the supplied {@link TagWriter}. 377 * Subclasses may choose to override this implementation to control exactly 378 * when the value is written. 379 */ 380 protected void writeValue(TagWriter tagWriter) throws JspException { 381 String value = getDisplayString(getBoundValue(), getPropertyEditor()); 382 String type = null; 383 Map<String, Object> attributes = getDynamicAttributes(); 384 if (attributes != null) { 385 type = (String) attributes.get("type"); 386 } 387 if (type == null) { 388 type = getType(); 389 } 390 tagWriter.writeAttribute("value", processFieldValue(getName(), value, type)); 391 } 392 393 /** 394 * Flags {@code type="checkbox"} and {@code type="radio"} as illegal 395 * dynamic attributes. 396 */ 397 @Override 398 protected boolean isValidDynamicAttribute(String localName, Object value) { 399 return !("type".equals(localName) && ("checkbox".equals(value) || "radio".equals(value))); 400 } 401 402 /** 403 * Get the value of the '{@code type}' attribute. Subclasses 404 * can override this to change the type of '{@code input}' element 405 * rendered. Default value is '{@code text}'. 406 */ 407 protected String getType() { 408 return "text"; 409 } 410 411}