我正在使用一个使用下拉列表和输入的复合组件。必填属性在下拉列表中设置,但如果'其他'如果选中,则还需要输入。我想在' cc.attr.value'上验证了必填字段,但我还需要验证' cc.attr.otherValue'。所以,我使用postValidate来检查这个必需的值。单击“保存”应验证组件内的输入,然后调用postValidate操作。但是,在postValidate之后,它仍然在更新模型阶段调用setter。
<composite:interface componentType="myInputComponent">
<composite:attribute name="value" required="true" type="java.lang.String" />
<composite:attribute name="otherValue" required="true" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<s:validateAll>
<s:span id="input">
<h:selectOneMenu id="selectInput" value="#{cc.attrs.value}"
required="#{cc.required}"
onchange="otherInput = #{rich:element('otherInput')}; otherInput.value = ''; if (this.options[this.selectedIndex].text == 'Other') { otherInput.style.display = ''; otherInput.required = #{cc.required}; } else { otherInput.style.display = 'none'; otherInput.required = false; }">
<f:event type="postValidate" listener="#{cc.postValidate}" />
<!-- validators here -->
</h:selectOneMenu>
<s:span id="other">
<h:inputText id="otherInput" value="#{cc.attrs.otherValue}"
size="#{cc.attrs.width}" style="#{showOther ? '' : 'display: none'}"
onkeydown="#{not cc.attrs.inplace ? 'ignoreEnter(event)' : ''}"
onkeypress="#{cc.attrs.inplace ? 'saveOnEnter(event)' : ''}">
<f:event type="postValidate" listener="#{cc.postValidate}" />
</h:inputText>
</s:span>
</s:span>
<a4j:commandButton action="#{cc.attrs.saveAction}"
value="Save"
execute="input"
render="input" />
</s:validateAll>
</composite:implementation>
这是UIComponent
@FacesComponent("myInputComponent")
public class MyInputComponent extends UIInput implements NamingContainer {
static final String OTHER_INPUT_ID = "otherInput";
static final String OTHER_LABEL = "Other";
public void postValidate(ComponentSystemEvent event) {
UIInput input = (UIInput) event.getComponent();
if (input != null && OTHER_INPUT_ID.equals(input.getId())) {
UIInput selectInput = (UIInput) event.getComponent().findComponent("selectInput");;
boolean useOtherValue = false;
if (selectInput != null) {
Object value = selectInput.getValue();
useOtherValue = isUseOtherValue(value);
if (useOtherValue && isRequired()) {
String otherValue = (String) input.getValue();
if (StringUtils.emptyString(otherValue)) {
setInvalid(input);
showRequiredMessage(input);
}
}
}
}
}
private void setInvalid(UIInput input) {
input.setValid(false);
FacesContext.getCurrentInstance().validationFailed();
}
}
正在使用的组件:
<my:myInput value="#{bean.value}" otherValue="#{bean.otherValue}" />
在postValidate失败后仍然会调用bean.value上的setter。
我已经在只有一个输入的类似组件上尝试过此操作,当需要的值失败时,它会按预期工作。它不会进入制定者。