我正在使用JSF 2.0。
我的页面上有一个包含值列表的h:selectOneMenu
,并且同一页面上有一个h:inputText
,其required
应取决于当前选择的h:selectOneMenu
值。只有一组特定的值应触发required
检查,其他值则不会。
这是我尝试过的:
<h:inputText ... required="#{(selectedPaymentType.value == 'some value') || (selectedPaymentType.value == 'other value')}" />
在上面的代码中,#{selectedPaymentType}
在 h:selectOneMenu binding
中定义。
还有 3 个这样的值应该触发 required
属性以true
。这看起来有点笨拙。有没有更好的方法可以做到这一点?
Fant 给出了正确的提示,您应该使用具有required
属性的枚举,但似乎您并不完全确定如何正确实现它。诚然,范特的回答不够详细。所以这里有一个更详细的答案。
基本上,您需要将所有下拉值替换为如下所示的枚举:
public enum PaymentType {
FOO("Some label for foo", true),
BAR("Some label for bar", false),
BAZ("Some label for baz", true);
private String label;
private boolean required;
private PaymentType(String label, boolean required) {
this.label = label;
this.required = required;
}
public String getLabel() {
return label;
}
public boolean isRequired() {
return required;
}
}
并按如下方式使用它
<h:selectOneMenu binding="#{selectedPaymentType}" value="#{bean.selectedPaymentType}">
<f:selectItems value="#{bean.availablePaymentTypes}" var="paymentType"
itemValue="#{paymentType}" itemLabel="#{paymentType.label}" />
</h:selectOneMenu>
<h:inputText ... required="#{selectedPaymentType.value.required}" />
跟
private PaymentType selectedPaymentType; // +getter+setter
public PaymentType[] getAvailablePaymentTypes() {
return PaymentType.values();
}
(或者如果你使用的是OmniFaces,使用<o:importConstants>
,那么你不需要这样的<f:selectItems>
getter;不,在任何情况下你都不需要转换器,JSF/EL已经内置了枚举的转换)
看,required
属性现在更加简化,因为它已经在与所选值关联的模型中定义。
如果在你的设计中可能的话,你可以使用枚举作为你的支付类型,其中包括一些接口,如
public interface RequireSomeMoreStuff {
public boolean required();
}
public enum PaymentType implements RequireSomeMoreStuff {
FOO { boolean required() { return true; } },
BAR { boolean required() { return false; } }
}
我会使用 a4j
来仅在选择了selectOneMenu
的某些值时才呈现 inputText:
<h:selectOneMenu value="#{MyBean.selectedValue}">
<f:selectItems value="#{MyBean.listOfValues}" />
<a4j:support event="onchange" reRender="requiredText" ajaxSingle="true"/>
</h:selectOneMenu>
<a4j:outputPanel id="requiredText">
<h:inputText value="#{MyBean.inputValue}" rendered="#{(MyBean.selectedValue == value_1) || (MyBean.selectedValue == value_2) || ...}" />
</a4j:outputPanel>
为了避免在inputText的rendered
参数上出现大字符串,我建议您创建一个执行这些条件的布尔函数:rendered="#{MyBean.inputTextIsRendered}
。
客户端解决方案
还有一个基于验证器的解决方案。这是我的方法:
JSF 代码
上面的selectOneMenu
代码使用 binding
标记将selectOneMenu
中选择的值与将在验证器方法中检索的属性绑定,该属性是为inputText
组件声明的
- 验证器类
然后,您需要创建CheckInputValue
验证程序类。
public class CheckInputValue implements Validator {
public CheckInputValue() {}
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
//We retrieve thei binded value:
UIInput confirmComponent = (UIInput) component.getAttributes().get("selectedValue");
String theValue = confirmComponent.getSubmittedValue();
//Here you check the retrieved value with the list of values that makes your inputText required.
//In these cases you will chech the inputText is not empty and, if so, you return a ValidatorException:
if(isEmpty){
FacesMessage message = new FacesMessage();
message.setDetail("inputText cannot be empty");
message.setSummary("inputText cannot be empty");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
}
- 人脸配置.xml
最后,您必须在 faces-config.xml
中声明您的验证器类:
<validator>
<validator-id>CheckInputValue</validator-id>
<validator-class>myPackage.myValidations.CheckInputValue</validator-class>
</validator>