我有一个用户必须填写的大型申请表。它由几个表放在各自的<ui:include>
中。我有一个自定义验证器,需要验证位于不同表中的多个输入字段。这是一个简单版本的外观:
<div class="tableContainer">
<ui:include src="applications/edit/info1.xhtml"/>
<ui:include src="applications/edit/info2.xhtml"/>
</div>
<h:commandButton id="validateButton">
<a4j:ajax oncomplete="if (#{!facesContext.validationFailed})displayModal()"/>
</h:commandButton>
<ui:composition>
<rich:dataTable id="info1">
<rich:columnGroup>
<rich:column>
inputField1
</rich:column>
<rich:column>
<h:inputText id="inputText1">
<f:validator validatorId="customValidator"/>
<f:attribute name="inputText2" value="inputText2"/>
<f:attribute name="inputText3" value="inputText3"/>
</h:inputText>
</rich:column>
</rich:columnGroup>
<rich:columnGroup>
<rich:column>
inputField2
</rich:column>
<rich:column>
<h:inputText id="inputText2" binding="#{inputText2}"/>
</rich:column>
</rich:columnGroup>
</rich:dataTable>
</ui:composition>
<ui:composition>
<rich:dataTable id="info2">
<rich:columnGroup>
<rich:column>
inputField3
</rich:column>
<rich:column>
<h:inputText id="inputText3" binding="#{inputText3}"/>
</rich:column>
</rich:columnGroup>
</rich:dataTable>
</ui:composition>
UIInput inputText2Component = (UIInput) component.getAttributes().get("inputText2");
UIInput inputText3Component = (UIInput) component.getAttributes().get("inputText3");
//do some validation
inputText2Component.setValid(false);
context.addMessage(inputText2Component.getClientId(), "Validation error message");
inputText3Component.setValid(false);
context.addMessage(inputText3Component.getClientId(), "Validation error message");
if (context.getMessageList().size > 0) {
context.validationFailed();
throw new ValidationException(new FacesMessage);
}
此处的问题是未正确识别另一个表inputText3Component
中的组件。 inputText3Component.getClientId()
返回错误的ID,inputText3Component.setValid(false)
未生效,并且未显示验证消息,可能是因为ID不正确,但inputText3Component.getValue()
正是它应该是的。
inputText2Component.getClientId()
生成"form:info1:0:inputText2"
,而
inputText3Component.getClientId()
生成"form:info2:inputText3"
。由于某种原因,:0:
部分被省略。
现在,如果我破解这样的代码:
inputText3Component.setValid(false);
context.addMessage("form:info2:0:inputText3", "Validation error message");
强制:0:
部分在那里,然后按原样添加消息。
此外,我不知道,如果这是自定义验证的特性,但是validationFailed()
没有为上下文设置。因此,oncomplete="if (#{!facesContext.validationFailed})displayModal()"
也无效。
问题是如何获得正确的组件ID和上下文验证状态?