I have a h:selectOneListbox which has the attribute required="true". Client side validation with a4j:ajax works fine.
If a valid selection is done, another panelgroup is rendered.
Example:
<h:selectOneListbox
....
id="first"
....
required="true"
>
<a4j:ajax event="valueChange" render="secondGroup" listener="#{myController.anotherMethodINeed}"/>
</h:selectOneListbox>
<!-- the other panel -->
<h:panelGroup id="secondGroup" layout="none">
<h:panelGroup id="secondGroupCheck" layout="none" rendered="#{not empty model.first}">
</h:panelGroup>
</h:panelGroup>
This also works.
Here’s the problem:
If the user now selects a illegal value on the first select box (like an empty one), then input is validated on client side. Hence the information never makes it to the model. After the first valid input, the panel is always rendered. There is no way to make it disappear again, since the server does not know of the change.
The only workaround I know is to make a custom validator for such a field. The validator sets then a flag if the panel needs to be rendered. This flag can then be used to decide if the panelgroup should be rendered.
Is there not a smarter way to do this?
I know that I can use something like rendered="#{not facesContext.validationFailed}" to check all the field, but I do not know a method to check just one field.
If an
UIInputcomponent throws aValidatorExceptionduring validations phase, then JSF will automatically callUIInput#setValid()withfalse. This thus means that you can useUIInput#isValid()in the view to check if the particular component has passed validation or not.You can use the
bindingattribute to bind anUIInputcomponent to the view and then access all its properties the usual EL way.By the way, the
layout="none"is an invalid attribute for<h:panelGroup>, so I omitted it. Also, theevent="valueChange"is the default already for<a4j|f:ajax>insideUIInputcomponents, so I omitted it.