Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
Components redisplaying model values when validation fails
Hi all,
I am experiencing an issue that can be reproduced by deploying the demo
JSF CDI Applicant Portlet
to liferay-ce-portal-7.1.0-ga1.
As I want to use bean validation in an upcoming project,
I added the context parameter to the web.xml and deployed it to LR for testing...
Now, if validation fails for a required input value, the (old) model value is redisplayed.
Steps to reproduce:
1) Enter only "first name"
2) Submit
3) Remove value from "first name" again
4) Submit
Now the old value (from model) is redisplayed.
I am pretty sure that this behavior is related to the following issue:
https://github.com/javaee/javaserverfaces-spec/issues/671
https://stackoverflow.com/questions/3933786/jsf-2-bean-validation-validation-failed-empty-values-are-replaced-with-las
But none of the workarounds worked for me.
Any ideas?
Thanks
Abraham
I am experiencing an issue that can be reproduced by deploying the demo
JSF CDI Applicant Portlet
to liferay-ce-portal-7.1.0-ga1.
As I want to use bean validation in an upcoming project,
I added the context parameter to the web.xml and deployed it to LR for testing...
[code]<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>Now, if validation fails for a required input value, the (old) model value is redisplayed.
Steps to reproduce:
1) Enter only "first name"
2) Submit
3) Remove value from "first name" again
4) Submit
Now the old value (from model) is redisplayed.
I am pretty sure that this behavior is related to the following issue:
https://github.com/javaee/javaserverfaces-spec/issues/671
https://stackoverflow.com/questions/3933786/jsf-2-bean-validation-validation-failed-empty-values-are-replaced-with-las
But none of the workarounds worked for me.
Any ideas?
Thanks
Abraham
Kyle Joseph Stiemann, modified 6 Years ago.
Liferay Master
Posts: 760
Join Date: 1/14/13
Recent Posts
Hi Abraham,
As you noted, this is a bug in the JSF spec that has been fixed in JSF 2.3. There's no easy fix without changing Mojarra, but it may be possible to work around this issue using JSF extension points. Perhaps you could add a custom ResponseWriterWrapper that renders the "value" property as an empty string when appropriate:
You'll need to add this ResponseWriter using a custom RenderKit (example custom RenderKit in Liferay Faces) which is registered in your faces-config.xml file:
I haven't tested this code, and there are potential problems with this solution: certain renderers may omit the "value" property so it may not be possible to tell when they are rendering their value, this ResponseWriter may interfere with other ResponseWriters (and vice-versa) etc. But this is the best workaround I could come up with. Let me know if it works for you.
- Kyle
As you noted, this is a bug in the JSF spec that has been fixed in JSF 2.3. There's no easy fix without changing Mojarra, but it may be possible to work around this issue using JSF extension points. Perhaps you could add a custom ResponseWriterWrapper that renders the "value" property as an empty string when appropriate:
public final class CustomResponseWriter extends ResponseWriterWrapper{
private final ResponseWriter wrappedResponseWriter;
private final LinkedList<editablevalueholder> editableValueHolders;
public CustomResponseWriter(ResponseWriter responseWriter) {
this.wrappedResponseWriter = responseWriter;
this.editableValueHolders = new LinkedList<editablevalueholder>();
}
@Override
public void writeText(Object text, UIComponent uiComponent, String property) throws IOException {
if (shouldRenderAsEmptyString(property)) {
super.writeText("", uiComponent, property);
}
else {
super.writeText(text, uiComponent, property);
}
}
@Override
public void writeText(Object text, String property) throws IOException {
if (shouldRenderAsEmptyString(property)) {
super.writeText("", property);
}
else {
super.writeText(text, property);
}
}
@Override
public void writeURIAttribute(String name, Object value, String property) throws IOException {
if (shouldRenderAsEmptyString(property)) {
super.writeURIAttribute(name, "", property);
}
else {
super.writeURIAttribute(name, value, property);
}
}
@Override
public void writeAttribute(String name, Object value, String property) throws IOException {
if (shouldRenderAsEmptyString(property)) {
super.writeAttribute(name, "", property);
}
else {
super.writeAttribute(name, value, property);
}
}
@Override
public void startElement(String name, UIComponent uiComponent) throws IOException {
if (uiComponent instanceof EditableValueHolder) {
editableValueHolders.push((EditableValueHolder) uiComponent);
}
else {
editableValueHolders.push(null);
}
super.startElement(name, uiComponent);
}
@Override
public void endElement(String name) throws IOException {
super.endElement(name);
editableValueHolders.pop();
}
private boolean shouldRenderAsEmptyString(String property) {
return "value".equalsIgnoreCase(property) &&
editableValueHolders.peek() != null &&
editableValueHolders.peek().getSubmittedValue() == null &&
!editableValueHolders.peek().isValid();
}
@Override
public ResponseWriter getWrapped() {
return wrappedResponseWriter;
}
}</editablevalueholder></editablevalueholder>You'll need to add this ResponseWriter using a custom RenderKit (example custom RenderKit in Liferay Faces) which is registered in your faces-config.xml file:
<render-kit>
<render-kit-id>HTML_BASIC</render-kit-id>
<render-kit-class>your.custom.renderkit.CustomRenderKit</render-kit-class>
</render-kit>I haven't tested this code, and there are potential problems with this solution: certain renderers may omit the "value" property so it may not be possible to tell when they are rendering their value, this ResponseWriter may interfere with other ResponseWriters (and vice-versa) etc. But this is the best workaround I could come up with. Let me know if it works for you.
- Kyle