如何让 h:inputText 的必需属性依赖于 h:selectOneMenu 中的某些值集?
Posted
技术标签:
【中文标题】如何让 h:inputText 的必需属性依赖于 h:selectOneMenu 中的某些值集?【英文标题】:How to let the required attribute of h:inputText depend on certain set of values from h:selectOneMenu? 【发布时间】:2012-11-10 02:44:54 【问题描述】:我正在使用 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
。这看起来有点笨拙。有更好的方法吗?
【问题讨论】:
【参考方案1】: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>
,您不需要这样的吸气剂;不,无论如何您都不需要转换器,JSF/ EL 已经内置了枚举转换)
看,required
属性现在已经简化了很多,因为它已经在与所选值关联的模型中定义了。
【讨论】:
谢谢。现在我明白了如何用枚举来实现它。但我不能这样做,它是一个列表。那么函数isRequired()
在这种情况下我最好的选择?
我不明白这究竟是如何形成问题的。 “它的列表”是什么意思?字符串列表?从哪里?数据库?您的具体问题不是您不确定如何将枚举用作数据库值吗?
抱歉,这不是一个列表。我将它与用于填充 selectOneMenu 的列表混淆了。是的,我可以将其更改为枚举。我确实知道有关 ising 枚举的基础知识。我想我现在就可以了。谢谢你:-)【参考方案2】:
如果在您的设计中可能,您可以使用枚举作为您的 PaymentType,其中包括一些类似的接口
public interface RequireSomeMoreStuff
public boolean required();
public enum PaymentType implements RequireSomeMoreStuff
FOO boolean required() return true; ,
BAR boolean required() return false;
【讨论】:
感谢您的快速回复。但即使我这样做了……那不是服务器端验证吗?我正在寻找客户端的东西。 是的,因为您的解决方案已经如此。但是现在 JSF 中的代码将更短且可读性更好。如果您添加或删除一些 PaymentTypes,您不必更改 jsf 中的某事。我以为那是你要找的地方。 --- 如果你想要一些客户端验证,你必须使用一些 javascript 或类似的东西。但我认为(仅)在客户端进行验证并不是一个好主意,因为您总是可以绕过客户端验证。 请参阅 here 了解我想要实现的目标。selectedPaymentType
是 selectOneMenu
上的绑定,而不是 bean 属性。所以我想这应该是客户端。虽然不确定【参考方案3】:
只有在您的selectOneMenu
的某些值被选中时,我才会使用a4j
来呈现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);
faces-config.xml
最后,您必须在faces-config.xml
中声明您的验证器类:
<validator>
<validator-id>CheckInputValue</validator-id>
<validator-class>myPackage.myValidations.CheckInputValue</validator-class>
</validator>
【讨论】:
Ajax4jsf 的答案没有意义。你没有理解具体的问题。 OP 的代码有效,但他发现required
属性中的EL 表达式非常笨拙。此外,用过时的 JSF 1.x 特定方法回答 JSF 2.x 问题是没有意义的(您可以只使用 JSF 2.x 自己的<f:ajax>
)。此外,您的验证器示例绝对不是“客户端解决方案”。这个答案在所有领域都是错误的。以上是关于如何让 h:inputText 的必需属性依赖于 h:selectOneMenu 中的某些值集?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JSF 中构建“编辑”按钮并在 h:outputText 和 h:inputText 之间切换
绑定到 Integer 属性的 h:inputText 正在提交值 0 而不是 null
如何在 h:inputTextarea 上设置 maxlength 属性