Hidden fields do not support input validation as well. Shouldn't the
implementation extend AbstractField?
I put together snippets from the existing Hidden field and the
AbstractTextField which works for me now. I don't oversee all the
elements so this is just a raw idea. I am not sure, if we shouldn't
allow validation for hidden fields.
public class Hidden extends AbstractField{
/**
* The value to read (when rendering) or update (when the form is
submitted).
*/
@Parameter(required = true, autoconnect = true, principal = true)
private Object value;
/**
* Value encoder for the value, usually determined automatically from
the type of the property bound to the value
* parameter.
*/
@Parameter(required = true)
private ValueEncoder encoder;
private String controlName;
@Inject
private Request request;
@Inject
private FieldValidationSupport fieldValidationSupport;
@Inject
private ComponentResources resources;
/**
* The object which will perform translation between server-side and
client-side representations. If not specified,
* a value will usually be generated based on the type of the value
parameter.
*/
@Parameter(required = true, allowNull = false, defaultPrefix =
BindingConstants.TRANSLATE)
private FieldTranslator<Object> translate;
/**
* The object that will perform input validation (which occurs after
translation). The validate binding prefix is
* generally used to provide this object in a declarative fashion.
*/
@Parameter(defaultPrefix = BindingConstants.VALIDATE)
@SuppressWarnings("unchecked")
private FieldValidator<Object> validate;
/**
* Defines how nulls on the server side, or sent from the client side,
are treated. The selected strategy may
* replace the nulls with some other value. The default strategy leaves
nulls alone. Another built-in strategy,
* zero, replaces nulls with the value 0.
*/
@Parameter(defaultPrefix = BindingConstants.NULLFIELDSTRATEGY, value =
"default")
private NullFieldStrategy nulls;
@Environmental(false)
private FormSupport formSupport;
@Environmental
private ValidationTracker tracker;
@Inject
private ComponentDefaultProvider defaultProvider;
ValueEncoder defaultEncoder() {
return defaultProvider.defaultValueEncoder("value", resources);
}
final Binding defaultTranslate() {
return defaultProvider.defaultTranslatorBinding("value",
resources);
}
/**
* Computes a default value for the "validate" parameter using {...@link
org.apache.tapestry5.services.FieldValidatorDefaultSource}.
*/
final Binding defaultValidate() {
return defaultProvider.defaultValidatorBinding("value",
resources);
}
/**
* The default value is a property of the container whose name matches
the component's id. May return null if the
* container does not have a matching property.
*
* @deprecated Likely to be removed in the future, use {...@link
org.apache.tapestry5.annotations.Parameter#autoconnect()}
* instead
*/
final Binding defaultValue() {
return createDefaultParameterBinding("value");
}
static class ProcessSubmission implements ComponentAction<Hidden> {
private final String controlName;
public ProcessSubmission(String controlName) {
this.controlName = controlName;
}
public void execute(Hidden component) {
component.processSubmission(controlName);
}
}
boolean beginRender(MarkupWriter writer) {
if (formSupport == null)
throw new RuntimeException("The Hidden component must be enclosed by
a Form component.");
controlName =
formSupport.allocateControlName(resources.getId());
formSupport.store(this, new ProcessSubmission(controlName));
String encoded = encoder.toClient(value);
writer.element("input",
"type", "hidden",
"name", controlName,
"value", encoded);
writer.end();
return false;
}
protected void processSubmission(String elementName) {
String rawValue = request.getParameter(elementName);
try {
Object translated = fieldValidationSupport.parseClient(rawValue,
resources, translate, nulls);
fieldValidationSupport.validate(translated, resources,
validate);
if (!(InternalUtils.isBlank(rawValue)))
value = translated;
}
catch (ValidationException ex) {
tracker.recordError(ex.getMessage());
}
}
}
Sebastian Hennebrueder schrieb:
Hello,
an empty hidden field is not properly decoded. If foo is null, I get
Caused by: java.lang.RuntimeException: Coercion of to type
java.lang.Integer (via String --> Long, Long --> Integer) failed: For
input string: ""
at
org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl$TargetCoercion.coerce(TypeCoercerImpl.java:69)
at
org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:133)
at $TypeCoercer_1230b108ecc.coerce($TypeCoercer_1230b108ecc.java)
at
org.apache.tapestry5.internal.services.TypeCoercedValueEncoderFactory$1.toValue(TypeCoercedValueEncoderFactory.java:45)
at
org.apache.tapestry5.corelib.components.Hidden.processSubmission(Hidden.java:109)
a
Here is the sample form I used.
Could someone confirm that this is a bug or not?
<t:form>
<t:hidden t:id="foo" value="foo"/>
<t:submit/>
</t:form>
public class Sample {
@Property
private Integer foo;
Object onSuccess(){
System.out.println(foo);
return null;
}
}
--
Best Regards / Viele Grüße
Sebastian Hennebrueder
-----
Software Developer and Trainer for Hibernate / Java Persistence
http://www.laliluna.de
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org