SPR-8694 HTML5 updates to the "type" attribute of the Spring Form tags.
Since dynamic attributes were allowed in Spring 3, it raised the possibility to specify a type attribute on a number of the form tags. Where it makes sense (see below) that attribute is now rejected and reversely where it makes sense it is accepted. InputTag allows types other than "text" but rejects type="radio" or type="checkbox" since there is a good reason for those to be used only in conjunction with the appropriate form library tags. Other HTML input tags such as PasswordTag, HiddenInputTag, Checkbox(es)Tag and RadioBox(es)Tag check the dynamic attributes and reject them if they contain a type attribute since.
This commit is contained in:
parent
e8dd35ce5e
commit
c290a4e68a
|
|
@ -17,6 +17,8 @@ Changes in version 3.1 RC2 (2011-11-15)
|
||||||
* fixed StandardServlet/PortletEnvironment to check for JNDI (for Google App Engine compatibility)
|
* fixed StandardServlet/PortletEnvironment to check for JNDI (for Google App Engine compatibility)
|
||||||
* Use original request URI in FlashMap matching logic to account for URL rewriting
|
* Use original request URI in FlashMap matching logic to account for URL rewriting
|
||||||
* Support target request with multiple parameter values in FlahMap matching logic
|
* Support target request with multiple parameter values in FlahMap matching logic
|
||||||
|
* Fix issue in SimpleMappingExceptionResolver causing exception when setting "statusCodes" property
|
||||||
|
* The Form input tag allows type values other than "text" such as HTML5-specific types.
|
||||||
|
|
||||||
Changes in version 3.1 RC1 (2011-10-11)
|
Changes in version 3.1 RC1 (2011-10-11)
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import javax.servlet.jsp.JspException;
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCheckedElementTag extends AbstractHtmlInputElementTag {
|
public abstract class AbstractCheckedElementTag extends AbstractHtmlInputElementTag {
|
||||||
|
|
@ -88,6 +89,14 @@ public abstract class AbstractCheckedElementTag extends AbstractHtmlInputElement
|
||||||
@Override
|
@Override
|
||||||
protected abstract int writeTagContent(TagWriter tagWriter) throws JspException;
|
protected abstract int writeTagContent(TagWriter tagWriter) throws JspException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags "type" as an illegal dynamic attribute.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isValidDynamicAttribute(String localName, Object value) {
|
||||||
|
return !"type".equals(localName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the type of the HTML input element to generate:
|
* Return the type of the HTML input element to generate:
|
||||||
* "checkbox" or "radio".
|
* "checkbox" or "radio".
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.DynamicAttributes;
|
import javax.servlet.jsp.tagext.DynamicAttributes;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
@ -37,6 +38,7 @@ import org.springframework.util.StringUtils;
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Jeremy Grelle
|
* @author Jeremy Grelle
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractHtmlElementTag extends AbstractDataBoundFormElementTag implements DynamicAttributes {
|
public abstract class AbstractHtmlElementTag extends AbstractDataBoundFormElementTag implements DynamicAttributes {
|
||||||
|
|
@ -396,9 +398,20 @@ public abstract class AbstractHtmlElementTag extends AbstractDataBoundFormElemen
|
||||||
if (this.dynamicAttributes == null) {
|
if (this.dynamicAttributes == null) {
|
||||||
this.dynamicAttributes = new HashMap<String, Object>();
|
this.dynamicAttributes = new HashMap<String, Object>();
|
||||||
}
|
}
|
||||||
|
if (!isValidDynamicAttribute(localName, value)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Attribute " + localName + "=\"" + value + "\" is not allowed");
|
||||||
|
}
|
||||||
dynamicAttributes.put(localName, value);
|
dynamicAttributes.put(localName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the given name-value pair is a valid dynamic attribute.
|
||||||
|
*/
|
||||||
|
protected boolean isValidDynamicAttribute(String localName, Object value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the default attributes configured via this base class to the supplied {@link TagWriter}.
|
* Writes the default attributes configured via this base class to the supplied {@link TagWriter}.
|
||||||
* Subclasses should call this when they want the base attribute set to be written to the output.
|
* Subclasses should call this when they want the base attribute set to be written to the output.
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,20 @@ import javax.servlet.jsp.JspException;
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
public class HiddenInputTag extends AbstractHtmlElementTag {
|
public class HiddenInputTag extends AbstractHtmlElementTag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags "type" as an illegal dynamic attribute.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isValidDynamicAttribute(String localName, Object value) {
|
||||||
|
return !"type".equals(localName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the HTML '<code>input</code>' tag to the supplied {@link TagWriter} including the
|
* Writes the HTML '<code>input</code>' tag to the supplied {@link TagWriter} including the
|
||||||
* databound value.
|
* databound value.
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,18 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.tags.form;
|
package org.springframework.web.servlet.tags.form;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
|
|
||||||
import org.springframework.web.servlet.support.RequestDataValueProcessor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data-binding-aware JSP tag for rendering an HTML '<code>input</code>'
|
* Data-binding-aware JSP tag for rendering an HTML '<code>input</code>'
|
||||||
* element with a '<code>type</code>' of '<code>text</code>'.
|
* element with a '<code>type</code>' of '<code>text</code>'.
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
public class InputTag extends AbstractHtmlInputElementTag {
|
public class InputTag extends AbstractHtmlInputElementTag {
|
||||||
|
|
||||||
public static final String SIZE_ATTRIBUTE = "size";
|
public static final String SIZE_ATTRIBUTE = "size";
|
||||||
|
|
@ -142,7 +140,9 @@ public class InputTag extends AbstractHtmlInputElementTag {
|
||||||
tagWriter.startTag("input");
|
tagWriter.startTag("input");
|
||||||
|
|
||||||
writeDefaultAttributes(tagWriter);
|
writeDefaultAttributes(tagWriter);
|
||||||
tagWriter.writeAttribute("type", getType());
|
if (!hasDynamicTypeAttribute()) {
|
||||||
|
tagWriter.writeAttribute("type", getType());
|
||||||
|
}
|
||||||
writeValue(tagWriter);
|
writeValue(tagWriter);
|
||||||
|
|
||||||
// custom optional attributes
|
// custom optional attributes
|
||||||
|
|
@ -156,6 +156,10 @@ public class InputTag extends AbstractHtmlInputElementTag {
|
||||||
return SKIP_BODY;
|
return SKIP_BODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasDynamicTypeAttribute() {
|
||||||
|
return getDynamicAttributes() != null && getDynamicAttributes().containsKey("type");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the '<code>value</code>' attribute to the supplied {@link TagWriter}.
|
* Writes the '<code>value</code>' attribute to the supplied {@link TagWriter}.
|
||||||
* Subclasses may choose to override this implementation to control exactly
|
* Subclasses may choose to override this implementation to control exactly
|
||||||
|
|
@ -163,7 +167,22 @@ public class InputTag extends AbstractHtmlInputElementTag {
|
||||||
*/
|
*/
|
||||||
protected void writeValue(TagWriter tagWriter) throws JspException {
|
protected void writeValue(TagWriter tagWriter) throws JspException {
|
||||||
String value = getDisplayString(getBoundValue(), getPropertyEditor());
|
String value = getDisplayString(getBoundValue(), getPropertyEditor());
|
||||||
tagWriter.writeAttribute("value", processFieldValue(getName(), value, getType()));
|
String type = hasDynamicTypeAttribute() ? (String) getDynamicAttributes().get("type") : getType();
|
||||||
|
tagWriter.writeAttribute("value", processFieldValue(getName(), value, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags {@code type="checkbox"} and {@code type="radio"} as illegal
|
||||||
|
* dynamic attributes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isValidDynamicAttribute(String localName, Object value) {
|
||||||
|
if ("type".equals(localName)) {
|
||||||
|
if ("checkbox".equals(value) || "radio".equals(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import javax.servlet.jsp.JspException;
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Rick Evans
|
* @author Rick Evans
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public class PasswordInputTag extends InputTag {
|
public class PasswordInputTag extends InputTag {
|
||||||
|
|
@ -47,6 +48,14 @@ public class PasswordInputTag extends InputTag {
|
||||||
this.showPassword = showPassword;
|
this.showPassword = showPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags "type" as an illegal dynamic attribute.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isValidDynamicAttribute(String localName, Object value) {
|
||||||
|
return !"type".equals(localName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return '<code>password</code>' causing the rendered HTML '<code>input</code>'
|
* Return '<code>password</code>' causing the rendered HTML '<code>input</code>'
|
||||||
* element to have a '<code>type</code>' of '<code>password</code>'.
|
* element to have a '<code>type</code>' of '<code>password</code>'.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
|
@ -610,6 +612,18 @@ public class CheckboxTagTests extends AbstractFormTagTests {
|
||||||
assertEquals("checked", checkboxElement.attribute("checked").getValue());
|
assertEquals("checked", checkboxElement.attribute("checked").getValue());
|
||||||
assertEquals("true", checkboxElement.attribute("value").getValue());
|
assertEquals("true", checkboxElement.attribute("value").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Date getDate() {
|
private Date getDate() {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.set(Calendar.YEAR, 10);
|
cal.set(Calendar.YEAR, 10);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
|
@ -703,6 +705,17 @@ public class CheckboxesTagTests extends AbstractFormTagTests {
|
||||||
assertEquals("element", spanElement.getName());
|
assertEquals("element", spanElement.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Date getDate() {
|
private Date getDate() {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.set(Calendar.YEAR, 10);
|
cal.set(Calendar.YEAR, 10);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package org.springframework.web.servlet.tags.form;
|
||||||
import org.springframework.beans.TestBean;
|
import org.springframework.beans.TestBean;
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -71,6 +72,16 @@ public class HiddenInputTagTests extends AbstractFormTagTests {
|
||||||
assertContainsAttribute(output, "value", "12.34f");
|
assertContainsAttribute(output, "value", "12.34f");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertTagClosed(String output) {
|
private void assertTagClosed(String output) {
|
||||||
assertTrue(output.endsWith("/>"));
|
assertTrue(output.endsWith("/>"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.web.servlet.tags.form;
|
||||||
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
import org.springframework.beans.TestBean;
|
import org.springframework.beans.TestBean;
|
||||||
|
|
@ -342,6 +343,39 @@ public class InputTagTests extends AbstractFormTagTests {
|
||||||
assertValueAttribute(output, "Rob");
|
assertValueAttribute(output, "Rob");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
this.tag.setPath("myFloat");
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "number");
|
||||||
|
|
||||||
|
assertEquals(Tag.SKIP_BODY, this.tag.doStartTag());
|
||||||
|
|
||||||
|
String output = getOutput();
|
||||||
|
assertTagOpened(output);
|
||||||
|
assertTagClosed(output);
|
||||||
|
|
||||||
|
assertContainsAttribute(output, "type", "number");
|
||||||
|
assertValueAttribute(output, "12.34");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeRadioAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "radio");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"radio\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeCheckboxAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "checkbox");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"checkbox\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected final void assertTagClosed(String output) {
|
protected final void assertTagClosed(String output) {
|
||||||
assertTrue("Tag not closed properly", output.endsWith("/>"));
|
assertTrue("Tag not closed properly", output.endsWith("/>"));
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.web.servlet.tags.form;
|
||||||
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -77,6 +78,15 @@ public class PasswordInputTagTests extends InputTagTests {
|
||||||
assertValueAttribute(output, "");
|
assertValueAttribute(output, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.getTag().setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void assertValueAttribute(String output, String expectedValue) {
|
protected void assertValueAttribute(String output, String expectedValue) {
|
||||||
if (this.getPasswordTag().isShowPassword()) {
|
if (this.getPasswordTag().isShowPassword()) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.beans.PropertyEditorSupport;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
|
@ -227,6 +228,16 @@ public class RadioButtonTagTests extends AbstractFormTagTests {
|
||||||
assertEquals("checked", checkboxElement.attribute("checked").getValue());
|
assertEquals("checked", checkboxElement.attribute("checked").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertTagOpened(String output) {
|
private void assertTagOpened(String output) {
|
||||||
assertTrue(output.indexOf("<input ") > -1);
|
assertTrue(output.indexOf("<input ") > -1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
|
@ -559,6 +560,16 @@ public final class RadioButtonsTagTests extends AbstractFormTagTests {
|
||||||
assertEquals("element", spanElement.getName());
|
assertEquals("element", spanElement.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDynamicTypeAttribute() throws JspException {
|
||||||
|
try {
|
||||||
|
this.tag.setDynamicAttribute(null, "type", "email");
|
||||||
|
fail("Expected exception");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Attribute type=\"email\" is not allowed", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Date getDate() {
|
private Date getDate() {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.set(Calendar.YEAR, 10);
|
cal.set(Calendar.YEAR, 10);
|
||||||
|
|
|
||||||
|
|
@ -231,9 +231,11 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
|
||||||
<section id="view-jsp-formtaglib-inputtag">
|
<section id="view-jsp-formtaglib-inputtag">
|
||||||
<title>The <literal>input</literal> tag</title>
|
<title>The <literal>input</literal> tag</title>
|
||||||
|
|
||||||
<para>This tag renders an HTML 'input' tag with type 'text' using the
|
<para>This tag renders an HTML 'input' tag using the bound value
|
||||||
bound value. For an example of this tag, see <xref
|
and type='text' by default. For an example of this tag, see <xref
|
||||||
linkend="view-jsp-formtaglib-formtag" />.</para>
|
linkend="view-jsp-formtaglib-formtag" />. Starting with Spring 3.1
|
||||||
|
you can use other types such HTML5-specific types like 'email',
|
||||||
|
'tel', 'date', and others.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="view-jsp-formtaglib-checkboxtag">
|
<section id="view-jsp-formtaglib-checkboxtag">
|
||||||
|
|
@ -805,6 +807,22 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
|
||||||
return "redirect:/owners/" + ownerId;
|
return "redirect:/owners/" + ownerId;
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="view-jsp-formtaglib-html5">
|
||||||
|
<title>HTML5 Tags</title>
|
||||||
|
|
||||||
|
<para>Starting with Spring 3, the Spring form tag library allows entering
|
||||||
|
dynamic attributes, which means you can enter any HTML5 specific attributes.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>In Spring 3.1, the form input tag supports entering a type attribute
|
||||||
|
other than 'text'. This is intended to allow rendering new HTML5 specific
|
||||||
|
input types such as 'email', 'date', 'range', and others. Note that
|
||||||
|
entering type='text' is not required since 'text' is the default type.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue