本文介绍ADF的SelectOneChoice控件的两个方面:
1. 运行时的数据模型变化;
2. 必填验证
1. 运行时的数据模型变化
当ADF给页面上添加SelectOneChoice控件时,不是直接把绑定的数据源每个项目的value设置到控件上,而是把数据源的每条项目
的索引值设置到控件上。在数据提交时,又会通过索引找到对应的选项,最后再把选项对应的值更新到模型层。
例如我们有下面的数据源:
<selectItems> <selectItem> <value>M</value> <label>Male</value> </selectItem> <selectItem> <value>F</value> <label>Female</value> </selectItem> </selectItems>
对应到selectOneChoice控件上的数据模型为:
<items> <item> <value>0</value> <label>Male</value> </item> <item> <value>1</value> <label>Female</value> </item> </items>
2. 必填验证
ADF提供了可配置的必填项目验证,我们只需要把控件的required属性设置为true就可以了,如下所示:
<af:selectOneChoice label="#{uiBundle['label.title.state']}" id="soc2" value="#{bindings.stateId.inputValue}" required='true'> <f:selectItems value="#{bindings.stateList.items}" id="si3"/> </af:selectOneChoice>
这里有一个前提条件:你需要把stateList(即LOV)数据源设置为不包含空行项目(即不选中"Inculde No Selection Item"),如下图:
区别在于:
1)未勾选“Incude "No Selection" Item”时,ADF在生成下拉列表时,会自动添加一条空项目作为第一条选项,这个选项的value和label都为空。当从下拉列表中选择一条选项之后,空白的选项就自动没有了。
2)勾选“Incude "No Selection" Item”时,ADF在生成下拉列表时,会自动添加一条空项目作为第一条选项,这个选项的value为"0",label为空。当从下拉列表中选择一条选项之后,空白的选项仍然在,不会消失。
很显然,当下拉列表是一个必填项时,1)的行为很符合我们的要求。但是当下拉列表不是必填项目时,我们可能在选择了一条选项之后,又想去掉原先的原则,显然1)就不能符合我们的要求了。这时候我们需要用2),没啥问题。
而当下拉列表是条件依赖必填时(当checkbox选中时,必填,否则不必填),显然我们还是需要使用2)。但是因为下拉列表保存的是索引值而不是真正的模型层的值,而此处的空白选项的值为0,所以即使我们设置了required='true',也不会弹出提示必填的消息,因为无法区分空白选项和真实有效的选项。
此处我们就需要重写AdfRichSelectOneChoice的getSubmittedValue方法,当我们判断选中的选项为第一项且它的label为空时,
我们就自动返回空字符串,而不是"0",代码如下:
/** * The function is used to override the getSubmittedValue for dropdown list * on the page to force the required validation to take effect when user * select a blank item in dropdown list. */ overrideSOCGetSubmittedValue = function() { AdfRichSelectOneChoice.prototype.getSubmittedValue = function() { var submittedValue = AdfUIEditableValue.prototype.getSubmittedValue.call(this); if (!this.getRequired()) { return submittedValue; } var items = this.getSelectItems(); var firstItem = null; if (items != null && items.length > 0) { firstItem = items[0]; } if (firstItem == null) { return submittedValue; } // when user select a blank item, then return submitted value as blank string // in order to let the required validation to take effect. if (firstItem.getValue() == submittedValue && firstItem.getLabel() == "") { return ""; } } }
然后在页面加载的时候,触发上面的javascript,这样我们就可以继续使用ADF提供的可配置必填验证了,代码如下:
<af:clientListener method="overrideSOCGetSubmittedValue" type="load"/>