How to highlight invalid components in JSF

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>

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.

Short URL for this post: http://blog.oio.de/ugLJE
This entry was posted in Java Web Frameworks and tagged , . Bookmark the permalink.

4 Responses to How to highlight invalid components in JSF

  1. Nice, article! There’s a component in OmniFaces that does this highlighting for all components automatically. See http://showcase.omnifaces.org/components/highlight

    • Thomas Asel Thomas Asel says:

      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

  2. Pingback: JSF 2.0 Tutorial « Latest-Tutorial

Leave a Reply