M.R.
M.R.

Reputation: 2019

How to check and react on validation fault, while using ajax

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.

Upvotes: 1

Views: 157

Answers (1)

BalusC
BalusC

Reputation: 1109745

If an UIInput component throws a ValidatorException during validations phase, then JSF will automatically call UIInput#setValid() with false. This thus means that you can use UIInput#isValid() in the view to check if the particular component has passed validation or not.

You can use the binding attribute to bind an UIInput component to the view and then access all its properties the usual EL way.

<h:selectOneListbox id="first" binding="#{first}" ... required="true">
    ...
    <a4j:ajax listener="#{myController.anotherMethodINeed}" render="secondGroup" />
</h:selectOneListbox>

<h:panelGroup id="secondGroup">
    <h:panelGroup id="secondGroupCheck" rendered="#{not empty model.first and first.valid}">
        ...
    </h:panelGroup>
</h:panelGroup>

By the way, the layout="none" is an invalid attribute for <h:panelGroup>, so I omitted it. Also, the event="valueChange" is the default already for <a4j|f:ajax> inside UIInput components, so I omitted it.

Upvotes: 1

Related Questions