2

我带着一个关于 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 一起使用,验证器将确实有错误的 clientIds 放入 PhaseListener 访问的列表中)。

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

4

1 回答 1

2

如果消息出现两次,则意味着您要么由两个组件触发相同的验证器,要么验证器被触发一次但隐式地将消息添加到另一个组件。

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

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

例如在视图中:

<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 中有另一种方式来突出显示无效字段。您可以通过#{component}EL 中的新隐式变量来做到这一点:

<h:inputText styleClass="#{component.valid ? '' : 'error'}" />
于 2011-12-23T13:19:25.887 回答