将错误消息链接到JSF2中的多个UIComponent

时间:2011-12-23 12:29:17

标签: jsf-2 validation facescontext

我要问一个关于JSF2的问题。我目前正在混合BalusC在他博客上提出的两段不同的代码:

http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html

http://balusc.blogspot.com/2007/12/validator-for-multiple-fields.html

第一个让红色突出显示有错误消息的字段。 第二个允许在多个字段上执行验证。

我正在寻找一种方法来将FacesContext中的单个错误消息(不希望消息呈现两次)链接到多个客户端ID(因为由于多个字段验证器,消息确实涉及多个字段)

语言基础是否可行? 如果可以,我想避免使用手工制作的系统(它应该与具有“请求”范围的托管bean一起使用,验证器将具有错误的clientId放入由PhaseListener访问的List中。) p>

提前感谢您的提示。无法在FacesContext上看到任何接近addMessage()的东西可以完成工作,但也许有办法......

1 个答案:

答案 0 :(得分:2)

如果消息出现两次,则表示您要么通过两个组件触发相同的验证器,要么触发验证器一次,但是隐式地将消息添加到另一个组件。

我知道您希望将两个组件标记为无效(以便突出显示它们)并且您只想要一条消息。在这种情况下,您需要确保验证器被触发一次,而另一个组件正在检索空/空消息。

您只需要更改验证器以将整个组件检索为属性而不是其值(注意:我在此期间相应地编辑了旧文章;它有另一个好处)并且您需要将阶段监听器更改为删除空/空消息。

E.g。在视图中:

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

<h:outputLabel for="confirm" value="Confirm password" />
<h:inputSecret id="confirm" binding="#{confirm}" required="true" />
<h:message for="confirm" styleClass="error" />

并在validate()方法中:

String password = (String) value;
UIInput confirmComponent = (UIInput) component.getAttributes().get("confirm");
String confirm = confirmComponent.getSubmittedValue();

if (password == null || password.isEmpty() || confirm == null || confirm.isEmpty()) {
    return; // Let required="true" do its job.
}

if (!password.equals(confirm)) {
    confirmComponent.setValid(false);
    context.addMessage(confirmComponent.getClientId(context), new FacesMessage(null));
    throw new ValidatorException(new FacesMessage("Passwords are not equal."));
}

并在阶段监听器中:

Iterator<String> clientIdsWithMessages = facesContext.getClientIdsWithMessages();

while (clientIdsWithMessages.hasNext()) {
    String clientIdWithMessages = clientIdsWithMessages.next();

    if (focus == null) {
        focus = clientIdWithMessages;
    }

    highlight.append(clientIdWithMessages);

    if (clientIdsWithMessages.hasNext()) {
        highlight.append(",");
    }

    Iterator<FacesMessage> messages = facesContext.getMessages(clientIdWithMessages);

    while (messages.hasNext()) {
        if (messages.next().getSummary() == null) {
            messages.remove(); // Remove empty messages.
        }
    }
}

相关:


对于具体问题

无关,在JSF2中还有另一种突出显示无效字段的方式。您可以通过EL中的新隐式#{component}变量来执行此操作:

<h:inputText styleClass="#{component.valid ? '' : 'error'}" />