仅当所有其他输入都有效时才验证 h:selectBooleanCheckbox

Validate a h:selectBooleanCheckbox only if all the other inputs are valid

我在 JSF 中有一个注册表单,我想验证新用户是否仅在表单中的所有其他字段都有效后才同意条款和条件。有什么方法可以在 JSF 中验证这一点吗?这是我的代码示例。

    <h:form id="registerForm">
        <table>

            //Other fields
            <tr>
                <td><h:outputText value="Username " /></td>
                <td><h:inputText id="fusername"
                        value="#{registerUser.username}">
                        <f:validator for="fusername" validatorId="usernameValidator" />
                    </h:inputText></td>
                <td><h:message for="fusername" style="color:red" /></td>
            </tr>

            <tr>
                <td><h:outputText value="Password: " /></td>
                <td><h:inputSecret id="fpassword"
                        value="#{registerUser.password}">
                        <f:validator for="fpassword" validatorId="passwordValidator" />
                    </h:inputSecret></td>
                <td><h:message for="fpassword" style="color:red" /></td>
            </tr>

            <tr>
                <td><h:outputText value="Repeat Password " /></td>
                <td><h:inputSecret id="repeatPassword"
                        value="#{registerUser.repeatPassword}">
                            <f:validator for="repeatPassword" validatorId="repeatPasswordValidator"/>
                            <f:attribute name="originalPassword" value="fpassword" /> 
                        </h:inputSecret></td>
                <td><h:message for="repeatPassword" style="color:red" /></td>
            </tr>
            <tr>
                <td><h:selectBooleanCheckbox
                        value="#{registerUser.agreeTermsAndConditions}" required="true"/></td>
                <td>I agree with the terms and condition.</td>
            </tr>


            <tr>
                <td />
                <td><h:commandButton action="#{registerUser.saveUser}"
                        value="Register" /></td>
            </tr>

        </table>
    </h:form>


</f:view>

您可以在保存方法中手动验证您的复选框,因为您已经通过了验证。请注意,您需要为您的复选框设置一个 ID 才能找到它。

public void saveUser(){
  if (!agreeTermsAndConditions) {
    FacesContext context = FacesContext.getCurrentInstance();
    // Tell JSF validation has failed
    context.validationFailed();
    // Get the component
    UIComponent component = context.getViewRoot().findComponent("registerForm:agreeTermsAndConditions");
    // Set it to invalid
    ((EditableValueHolder)component).setValid(false);
    // Create a message
    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "You must agree with the terms and conditions.", null);
    // Register the message for the component
    context.addMessage(component.getClientId(), message);
  }
  else {
    // Agreed, so save the user here
    ...
  }
}

并在您的视图中添加用于查找组件的 ID 和 h:message 以显示设置的消息。

<h:form id="registerForm">
  <table>
    ...
    <tr>
      <td><h:selectBooleanCheckbox id="agreeTermsAndConditions"
                                   value="#{registerUser.agreeTermsAndConditions}"/></td>
      <td>I agree with the terms and condition.</td>
      <td><h:message for="agreeTermsAndConditions" style="color:red" /></td>
    </tr>
    ...
  </table>
</h:form>

如果您只想将复选框设置为必填,而不考虑其他字段,请参阅:

前提是 "I agree" 复选框是表单的 最后一个 UIInput 组件(在一般的 UI 设计中,它实际上通常是!), 那么你就可以这样做:

<h:selectBooleanCheckbox ... required="#{not facesContext.validationFailed}" />

也就是说,JSF 从上到下处理输入组件,其顺序与它们在视图中声明的顺序完全相同。当 JSF 即将处理复选框时,它将重新评估 required 属性。在这种情况下,当 no 复选框上方的其他 UIInput 组件导致验证失败时,FacesContext#isValidationFailed() 将 return false因此该组件将被视为必需的。

但是还有另一个问题:<h:selectBooleanCheckbox>required 属性在默认情况下根本没有任何效果。因为,取消选中复选框时,提交的值将变为false,而不是nullomnifaces.RequiredCheckboxValidator 解决了这个特殊问题。

所以,总而言之:

<h:selectBooleanCheckbox ... required="#{not facesContext.validationFailed}">
    <f:validator validatorId="omnifaces.RequiredCheckboxValidator" />
</h:selectBooleanCheckbox>