Giving the user a hint about failed validation is essential in form based applications. Though JSF components offer a lot validation functionality there is no such thing as a “failedValidationStyleClass” attribute. However, with a little effort we are able to set a specific error style class for a component that failed the validation.
The base class for all input components is UIInput. UIInput offers the method isValid() which can be accessed via EL using the implicit component
object:
<h:inputText value="#{address.country}" required="true" styleClass="#{component.valid?'validation-ok':'validation-failed'}" />
Based on this simple example we can create a composite component that includes a label and shows the validation message for the input component if validation failed.
Here is the composites implementation:
<h:form> <h:panelGrid columns="2"> <comp:labelledInput label="Firstname:" value="#{address.firstName}" required="true" /> <comp:labelledInput label="Lastname:" value="#{address.lastName}" required="true" /> <comp:labelledInput label="Street:" value="#{address.street}" required="true" /> <comp:labelledInput label="Number:" value="#{address.number}" required="true" /> <comp:labelledInput label="ZIP:" value="#{address.zip}" required="true" validatorMessage="Please enter a valid zipcode"> <f:validateLength for="input" minimum="5" maximum="5" /> </comp:labelledInput> <comp:labelledInput label="City:" value="#{address.city}" required="true" /> </h:panelGrid> <h:commandButton value="submit" /> </h:form>
As you can see, validators can be attached to our composite and an optional validator message may be set.
This is what the composite looks like:
<cc:interface> <cc:attribute name="label" /> <cc:attribute name="value" /> <cc:attribute name="required" /> <cc:attribute name="requiredMessage" required="false" default="An input is required"/> <cc:attribute name="validatorMessage" required="false" default="Invalid input"/> <cc:editableValueHolder name="input" targets="input"/> </cc:interface> <cc:implementation> <div class="labelledInput"> <h:outputLabel id="label" value="#{cc.attrs.label}" for="input" styleClass="labelledInput-label" /> <h:inputText id="input" value="#{cc.attrs.value}" required="#{cc.attrs.required}" requiredMessage="#{cc.attrs.requiredMessage}" validatorMessage="#{cc.attrs.validatorMessage}" styleClass="labelledInput-input #{component.valid?'':'validation-failed'}" /> <h:panelGroup id="message" layout="block" styleClass="validation-hint" rendered="#{! cc.findComponent('input').valid}"> <h:message for="input"/> </h:panelGroup> </div> </cc:implementation>
The various parts of the component may be styled using the given css classes. As you can see, the panel containing the messages is rendered conditionally. The expression #{! cc.findComponent('input').valid}"
is used to determine if the input component passed or failed the validation.
Conclusion: JSF’s composite components are a powerful feature. The functionality for this labelled input component did not even require a single line of Java code.


There is also SystemEvent approach. http://blog.primefaces.org/?p=1170
Nice, article! There’s a component in OmniFaces that does this highlighting for all components automatically. See http://showcase.omnifaces.org/components/highlight
There is always something for every problem in OmniFaces ;-) I really like what you are doing and am a strong advocate for OmniFaces. On the other side I like to show what can be done with plain JSF. Anyway, thanks for noticing and keep up the good work
Pingback: JSF 2.0 Tutorial « Latest-Tutorial
” styleClass=”labelledInput-input #{ component.valid ? ” : ‘validation-failed’ }” /> ” Doesn’t work for me.
In the Eclipse, I am getting a warrning: “valid cannot be resolved as a member of component”. The first argument (”) is always returned. The second argument (‘validation-failed’) never applies.
I have no idea why valid cannot be used, isValid() cannot be used either.
I found the source of the problem.
In my project, the input was not being validated by tag. The validation is being performed on the server and I have no control over it.
In this scenario, the input is always valid. Except if the input has specified attribute required=”true”. In which case the input is valid unless it is empty.
It seems that in my scenario, I am unable to retrieve the information about validity of the input from server.