2

在我的 .jsp 中,我有两个 selectOneMenu 项目,它们为我提供了开始/结束年份。现在,如果选择的开始年份大于结束年份,我想显示一条错误消息。我该如何解决这个问题?

<h:selectOneMenu id="minYear" value="#{statistics.minYear}" style="width: 75px">
    <f:selectItems value="#{statistics.yearValues}" />
</h:selectOneMenu>

<h:selectOneMenu id="maxYear" value="#{statistics.maxYear}" style="width: 75px">
    <f:selectItems  value="#{statistics.yearValues}"/>
</h:selectOneMenu>

在我的支持 bean 中,如果范围有效与否,我有一个返回 true/false 的方法。

public boolean isYearValid() {
    return (getMaxYear() >= getMinYear());
}
4

1 回答 1

4

JSF 中的普通验证只能验证单个元素,因此您需要绕过此限制。至少有两种方法可以使用 JSF 进行跨字段验证。

  1. 您可以将验证器应用于最后一个元素(或最后一个隐藏元素)定义自定义验证器/方法,查找元素并进行验证。

  2. 像这样注册一个监听器PostValidateEvent<f:event type="postValidate" listener="#{myValidationBean.validateDates}"/>。其余过程与 1 中的完全相同。

验证方法中的元素查找:

UIComponent source = event.getComponent();
UIInput minInput = (UIInput) source.findComponent("minYear");
UIInput maxInput = (UIInput) source.findComponent("maxYear");

访问元素的值:

int minYear = ((Integer)minInput.getLocalValue()).intValue();
int maxYear = ((Integer)maxInput.getLocalValue()).intValue();

编辑:糟糕,忘记了验证消息部分。

String valMsg = "maxYear cannot be less than minYear";
FacesContext.getCurrentInstance().addMessage(source.getClientId(), new FacesMessage(valMsg, valMsg));

EDIT2:如果您使用事件侦听器进行验证并且验证失败,最好立即进入响应呈现阶段以避免在模型上设置无效数据。为此,请context.renderResponse();在发送错误消息后调用。

EDIT3:虽然 JSF2 已经引入了系统事件,但第一种方法在 JSF 1.x 中应该是可行的。当您获取上下文和由 JSF 传递给您的验证方法的组件时,查找和消息分派的细节略有不同。

public void validateMulti(FacesContext context, UIComponent component, Object value){
  ...
  UIInput minInput = (UIInput) component.findComponent("minYear");
  ...
  context.addMessage("minYear", new FacesMessage(valMsg, valMsg));
  ...
于 2012-06-04T13:09:45.717 回答