【问题标题】:How can I display ValidatorException and required="true" of same input field in different messages elements如何在不同的消息元素中显示相同输入字段的 ValidatorException 和 required="true"
【发布时间】:2012-04-17 22:39:02
【问题描述】:

我采用了以下 BalusC kickoff example 并通过添加提交按钮和附加 h:messages 并从 h:inputSecret's 中删除 f:ajax 对其进行了一些修改(当我离开时出于某种原因删除了 f:ajax第一个h:inputSecret 它立即显示第二个h:inputSecret 的“值是必需的”错误 - 但用户没有机会输入它...... ???

好的,长话短说:

我试图弄清楚如何在全局 h:messages 中而不是在密码字段的单个 h:message 中显示关于两个密码字段(密码不相等)的验证错误 我确实希望 required="true" 将显示在每个字段的<h:message...

但现在验证消息(由我的异常抛出)和 required="true" 显示在同一个地方

代码如下:

<h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
    <f:validator validatorId="confirmPasswordValidator" />
    <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
</h:inputSecret>
<h:message id="m_password" for="password" />

<h:outputLabel for="confirm" value="Password (again):" />
<h:inputSecret id="confirm" binding="#{confirmPassword}" required="true">
</h:inputSecret>
<h:message id="m_confirm" for="confirm" />

另外h:commandButtonh:messages 在该代码下方:

<h:commandButton value="doSomething" action="#{myBean.myAction}">
    <f:ajax execute="password confirm" render="m_password m_confirm"></f:ajax>
</h:commandButton>
<h:messages globalOnly="true" styleClass="validation_value_required"/>
@FacesValidator("confirmPasswordValidator")
public class ConfirmPasswordValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String password = (String) value;
        String confirm = (String) component.getAttributes().get("confirm");

        if (password == null || confirm == null) {
            return; // Just ignore and let required="true" do its job.
        }

        if (!password.equals(confirm)) {
            throw new ValidatorException(new FacesMessage("Passwords are not equal."));
        }
    }

}

还有

谢谢,

解决方案(感谢 BalusC)

变了

<f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />

<f:attribute name="confirm" value="#{confirmPassword}" />

String confirm = (String) component.getAttributes().get("confirm");

进入

UIInput confirmPasswordComponent = (UIInput) component.getAttributes().get("confirm");
String confirm = (String) confirmPasswordComponent.getSubmittedValue();

throw new ValidatorException(new FacesMessage("Passwords are not equal."));

进入

context.addMessage(null, new FacesMessage("Passwords are not equal."));
context.validationFailed();
((UIInput) component).setValid(false);
confirmPasswordComponent.setValid(false);
return;

【问题讨论】:

    标签: validation jsf jsf-2


    【解决方案1】:

    如果特定组件上的Validator 抛出ValidatorException,则其FacesMessage 将自动与调用Validator 的组件相关联。

    您需要在 null 客户端 ID 上手动添加 FacesMessage,以便它以 &lt;h:messages globalOnly="true"&gt; 结尾。您还需要在FacesContext 上手动设置validationFailed(),以便JSF 不会更新模型值或调用操作。如有必要(尽管建议),您还需要手动将组件标记为无效,以便任何适当的侦听器/树访问器(例如,用于突出显示)都会考虑到这一点。

    if (!password.equals(confirm)) {
        context.addMessage(null, new FacesMessage("Passwords are not equal."));
        context.validationFailed();
        ((UIInput) component).setValid(false);
        confirmPasswordComponent.setValid(false); // You'd need to pass it as component instead of as its submitted value in f:attribute.
    }
    

    顺便说一下,OmniFaces 项目有一个&lt;o:validateEqual&gt; 组件,它应该可以减少这个乏味。另见showcase example

    【讨论】:

    • 您需要将其作为组件传递,而不是作为其在 f:attribute 中提交的值。怎么样?
    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多