我要问一个关于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()的东西可以完成工作,但也许有办法......
答案 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'}" />