OmniFaces validateEquals 和复合组件
OmniFaces validateEquals and composite component
我将 JSF 2.3 与 Omnifaces 3.0 结合使用。
我正在尝试创建一个代表电子邮件文本字段的自定义组件。没什么特别的。
我得到了以下完美运行的代码
<h:form id="formAggiungiUtente">
<p:outputLabel for="inputTextEmail" value="#{msg['email']}"/>
<h:inputText id="inputTextEmail" pt:type="email" value="#{userController.userBean.mail}" class="form-control" required="true" requiredMessage="#{msg['email']} #{msg['campoObbligatorio']}" validatorMessage="#{msg['email']} #{msg['nonValido']}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
<p:outputLabel for="inputTextSecondEmail" value="#{msg['ripetiMail']}"/>
<h:inputText id="inputTextSecondEmail" pt:type="email" value="#{userController.secondMail}" class="form-control" required="true" requiredMessage="#{msg['ripetiMail']} #{msg['campoObbligatorio']}" validatorMessage="#{msg['ripetiMail']} #{msg['nonValido']}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
在应用程序的其他部分,我需要代表电子邮件文本字段的组件,因此第一步是创建如下内容
<h:form id="formAggiungiUtente">
<ui:include src="templates/mailTextField.xhtml">
<ui:param name="id" value="inputTextEmail" />
<ui:param name="label" value="#{msg['email']}" />
<ui:param name="value" value="#{userController.userBean.mail}" />
<ui:param name="required" value="true" />
<ui:param name="requiredMessage" value="#{msg['email']} #{msg['campoObbligatorio']}" />
<ui:param name="validatorMessage" value="#{msg['email']} #{msg['nonValido']}" />
</ui:include>
<ui:include src="templates/mailTextField.xhtml">
<ui:param name="id" value="inputTextSecondEmail" />
<ui:param name="label" value="#{msg['ripetiMail']}" />
<ui:param name="value" value="#{userController.secondMail}" />
<ui:param name="required" value="true" />
<ui:param name="requiredMessage" value="#{msg['ripetiMail']} #{msg['campoObbligatorio']}" />
<ui:param name="validatorMessage" value="#{msg['ripetiMail']} #{msg['nonValido']}" />
</ui:include>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
这里是 mailTextField.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<p:outputLabel for="#{id}" value="#{label}"/>
<h:inputText
id="#{id}"
pt:type="email"
value="#{value}"
class="form-control"
required="#{required}"
requiredMessage="#{requiredMessage}"
validatorMessage="#{validatorMessage}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
</ui:composition>
此外,此解决方案有效,但通过阅读大量答案,我了解到如果参数过多,可能需要创建自定义组件。因此,我使用 "cvl" 作为库名称
创建了以下组件
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<cc:interface>
<cc:attribute name="label" type="java.lang.String" default="#{msg['email']}" />
<cc:attribute name="value" type="java.lang.String" />
<cc:attribute name="required" type="java.lang.Boolean" default="true" />
<cc:attribute name="requiredMessage" type="java.lang.String" default="#{msg['email']} #{msg['campoObbligatorio']}" />
<cc:attribute name="validatorMessage" type="java.lang.String" default="#{msg['email']} #{msg['nonValido']}" />
</cc:interface>
<cc:implementation>
<p:outputLabel for="#{cc.clientId}" value="#{cc.attrs.label}"/>
<h:inputText
id="#{cc.clientId}"
pt:type="email"
value="#{cc.attrs.value}"
class="form-control"
required="#{cc.attrs.required}"
requiredMessage="#{cc.attrs.requiredMessage}"
validatorMessage="#{cc.attrs.validatorMessage}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
</cc:implementation>
</html>
现在我的页面是这样的
<h:form id="formAggiungiUtente">
<cvl:mailTextField
id="inputTextEmail"
value="#{userController.userBean.mail}"
/>
<cvl:mailTextField
id="inputTextSecondEmail"
value="#{userController.userBean.mail}"
requiredMessage="#{msg['ripetiMail']} #{msg['campoObbligatorio']}"
validatorMessage="#{msg['ripetiMail']} #{msg['nonValido']}"
/>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
问题是我不知道如何填充 validateEqual 的参数 "components",因为错误总是如下所示。
ValidateEqual attribute 'components' must refer UIInput client IDs. Client ID is of type 'javax.faces.component.UINamingContainer'
我尝试了很多组合,但都没有成功。
我做错了什么?
谢谢
by reading a lot of answers I've understood that if there're too many parameter may is the case to create a custom component
这个? When to use <ui:include>, tag files, composite components and/or custom components?说是创建标签文件,不是自定义组件,更不是复合组件。
如果您使用了标记文件,那么这个结构就可以正常工作。另一方面,复合组件是命名容器。这意味着他们在 children 之上添加了一个额外的客户端 ID 层,就像 <h:form>
和 <h:dataTable>
一样。您还应该在客户端 ID 搜索表达式中包括复合组件自己的 id
。它是这样的:
<cc:someComposite id="idOfComposite1" ... />
<cc:someComposite id="idOfComposite2" ... />
<o:validateEqual components="idOfComposite1:idOfInput idOfComposite2:idOfInput" />
复合实现具有:
<h:inputText id="idOfInput" ... />
因此,您只需修复复合组件,使其不再在 child JSF 组件的 id
属性中引用 #{cc.clientId}
。这是完全错误的。它应该仅用于包装复合组件实现的普通 HTML <span>
或 <div>
,然后使用 Rerendering composite component by ajax.
的唯一原因
我将 JSF 2.3 与 Omnifaces 3.0 结合使用。 我正在尝试创建一个代表电子邮件文本字段的自定义组件。没什么特别的。
我得到了以下完美运行的代码
<h:form id="formAggiungiUtente">
<p:outputLabel for="inputTextEmail" value="#{msg['email']}"/>
<h:inputText id="inputTextEmail" pt:type="email" value="#{userController.userBean.mail}" class="form-control" required="true" requiredMessage="#{msg['email']} #{msg['campoObbligatorio']}" validatorMessage="#{msg['email']} #{msg['nonValido']}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
<p:outputLabel for="inputTextSecondEmail" value="#{msg['ripetiMail']}"/>
<h:inputText id="inputTextSecondEmail" pt:type="email" value="#{userController.secondMail}" class="form-control" required="true" requiredMessage="#{msg['ripetiMail']} #{msg['campoObbligatorio']}" validatorMessage="#{msg['ripetiMail']} #{msg['nonValido']}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
在应用程序的其他部分,我需要代表电子邮件文本字段的组件,因此第一步是创建如下内容
<h:form id="formAggiungiUtente">
<ui:include src="templates/mailTextField.xhtml">
<ui:param name="id" value="inputTextEmail" />
<ui:param name="label" value="#{msg['email']}" />
<ui:param name="value" value="#{userController.userBean.mail}" />
<ui:param name="required" value="true" />
<ui:param name="requiredMessage" value="#{msg['email']} #{msg['campoObbligatorio']}" />
<ui:param name="validatorMessage" value="#{msg['email']} #{msg['nonValido']}" />
</ui:include>
<ui:include src="templates/mailTextField.xhtml">
<ui:param name="id" value="inputTextSecondEmail" />
<ui:param name="label" value="#{msg['ripetiMail']}" />
<ui:param name="value" value="#{userController.secondMail}" />
<ui:param name="required" value="true" />
<ui:param name="requiredMessage" value="#{msg['ripetiMail']} #{msg['campoObbligatorio']}" />
<ui:param name="validatorMessage" value="#{msg['ripetiMail']} #{msg['nonValido']}" />
</ui:include>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
这里是 mailTextField.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<p:outputLabel for="#{id}" value="#{label}"/>
<h:inputText
id="#{id}"
pt:type="email"
value="#{value}"
class="form-control"
required="#{required}"
requiredMessage="#{requiredMessage}"
validatorMessage="#{validatorMessage}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
</ui:composition>
此外,此解决方案有效,但通过阅读大量答案,我了解到如果参数过多,可能需要创建自定义组件。因此,我使用 "cvl" 作为库名称
创建了以下组件<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<cc:interface>
<cc:attribute name="label" type="java.lang.String" default="#{msg['email']}" />
<cc:attribute name="value" type="java.lang.String" />
<cc:attribute name="required" type="java.lang.Boolean" default="true" />
<cc:attribute name="requiredMessage" type="java.lang.String" default="#{msg['email']} #{msg['campoObbligatorio']}" />
<cc:attribute name="validatorMessage" type="java.lang.String" default="#{msg['email']} #{msg['nonValido']}" />
</cc:interface>
<cc:implementation>
<p:outputLabel for="#{cc.clientId}" value="#{cc.attrs.label}"/>
<h:inputText
id="#{cc.clientId}"
pt:type="email"
value="#{cc.attrs.value}"
class="form-control"
required="#{cc.attrs.required}"
requiredMessage="#{cc.attrs.requiredMessage}"
validatorMessage="#{cc.attrs.validatorMessage}">
<f:validator binding="#{emailJsfValidator}"/>
</h:inputText>
</cc:implementation>
</html>
现在我的页面是这样的
<h:form id="formAggiungiUtente">
<cvl:mailTextField
id="inputTextEmail"
value="#{userController.userBean.mail}"
/>
<cvl:mailTextField
id="inputTextSecondEmail"
value="#{userController.userBean.mail}"
requiredMessage="#{msg['ripetiMail']} #{msg['campoObbligatorio']}"
validatorMessage="#{msg['ripetiMail']} #{msg['nonValido']}"
/>
<o:validateEqual id="equal" components="inputTextEmail inputTextSecondEmail" message="#{msg['indirizziMailDiversi']}" />
</h:form>
问题是我不知道如何填充 validateEqual 的参数 "components",因为错误总是如下所示。
ValidateEqual attribute 'components' must refer UIInput client IDs. Client ID is of type 'javax.faces.component.UINamingContainer'
我尝试了很多组合,但都没有成功。 我做错了什么? 谢谢
by reading a lot of answers I've understood that if there're too many parameter may is the case to create a custom component
这个? When to use <ui:include>, tag files, composite components and/or custom components?说是创建标签文件,不是自定义组件,更不是复合组件。
如果您使用了标记文件,那么这个结构就可以正常工作。另一方面,复合组件是命名容器。这意味着他们在 children 之上添加了一个额外的客户端 ID 层,就像 <h:form>
和 <h:dataTable>
一样。您还应该在客户端 ID 搜索表达式中包括复合组件自己的 id
。它是这样的:
<cc:someComposite id="idOfComposite1" ... />
<cc:someComposite id="idOfComposite2" ... />
<o:validateEqual components="idOfComposite1:idOfInput idOfComposite2:idOfInput" />
复合实现具有:
<h:inputText id="idOfInput" ... />
因此,您只需修复复合组件,使其不再在 child JSF 组件的 id
属性中引用 #{cc.clientId}
。这是完全错误的。它应该仅用于包装复合组件实现的普通 HTML <span>
或 <div>
,然后使用 Rerendering composite component by ajax.