Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

It's common for a developer to want to apply a validator to all input fields that fall within a branch (subtree) of the component tree. For instance, the developer may decide to mark all the inputs as required or indicate that the Bean Validation constraints should be enforced on properties bound to the inputs. To make it easier for the developer to accomplish this task, JSF should allow a validator to be wrapped around a subtree, not just attached to an EditableValueHolder. The bean validation integration supports subtree validation by attaching the validator to it's parent. To align with <f:ajax>, the generic approach should require the validator to be wrapped around the subtree to which it applies.

Behavior

The validator should be applied to all EditableValueHolder components that appear within that branch of the component tree wrapped within the validator tag, unless trumped by a branch validator with the same ID nearer to the EditableValueHolder. If the nearer validator tag has a disabled attribute whose value is true, then the validator is disabled for that branch. The validator can be enabled on a nested branch or on the EditableValueHolder itself by the presence of a validator tag without the disabled attribute.

Of course, if a validator holds state, it cannot be assigned to more than one EditableValueHolder. Therefore, if the validator implements StateHolder, it should first be copied using the standard JSF serialization mechanism (saveState/restoreState) before being assigned to the EditableValueHolder. In this case, the validator on the branch is merely acting as a prototype.

The branch validators should be applied to the EditableValueHolder after any locally defined validator. If a validator with the same ID is already present on the EditableValueHolder, a second instance, coming from the branch, should not be added to the component.

Example

<h:form>
    <f:validateRequired>
        <h:panelGrid>
            <h:outputLabel value="First Name" for="firstName"/>
            <h:inputText id="firstName" value="#{userBean.firstName}"/>
            <h:outputLabel value="Last Name" for="lastName"/>
            <h:inputText id="lastName" value="#{userBean.lastName}"/>
        </h:panelGrid>
    </f:validateRequired>
</h:form>
<h:form>
    <f:validateBean validationGroups="userInfo">
        <h:panelGrid>
            <h:outputLabel value="First Name" for="firstName"/>
            <h:inputText id="firstName" value="#{userBean.firstName}"/>
            <h:outputLabel value="Last Name" for="lastName"/>
            <h:inputText id="lastName" value="#{userBean.lastName}"/>
        </h:panelGrid>
    </f:validateBean>
</h:form>