【问题标题】:OmniFaces validateEquals and composite componentOmniFaces validateEquals 和复合组件
【发布时间】:2018-06-19 00:10:42
【问题描述】:

我正在使用 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 属性“组件”必须引用 UIInput 客户端 ID。客户端 ID 的类型为“javax.faces.component.UINamingContainer”

我尝试了很多组合但没有成功。 我做错了什么? 谢谢

【问题讨论】:

    标签: validation jsf composite-component omnifaces


    【解决方案1】:

    通过阅读大量答案,我了解到如果参数过多,可能会出现创建自定义组件的情况

    这个? When to use <ui:include>, tag files, composite components and/or custom components?说是创建标签文件,不是自定义组件,更不是复合组件。

    如果您使用了标记文件,那么这个结构就可以正常工作。另一方面,复合组件是命名容器。这意味着他们在他们的孩子上添加了一个额外的客户端 ID 层,就像 &lt;h:form&gt; 和 &lt;h:dataTable&gt; 一样。您还应该在客户端 ID 搜索表达式中包含复合组件自己的 id。它是这样的:

    <cc:someComposite id="idOfComposite1" ... />
    <cc:someComposite id="idOfComposite2" ... />
    
    <o:validateEqual components="idOfComposite1:idOfInput idOfComposite2:idOfInput" />
    

    其中复合实现具有:

    <h:inputText id="idOfInput" ... />
    

    因此,您只需修复您的复合组件,使其不再在子 JSF 组件的 id 属性中引用 #{cc.clientId}。这是完全错误的。它应该仅用于包装复合组件实现的纯 HTML &lt;span&gt; 或 &lt;div&gt;,然后使用 Rerendering composite component by ajax 的唯一原因。

    【讨论】:

    • 它正在工作。唯一的问题是 p:outputLabel 没有突出显示。正确调用了所有验证器(必需和 emailJsfValidator),但我没有将“*”视为必填字段,并且在出现验证错误时该字段未突出显示。我发现了这个问题。有关系吗? stackoverflow.com/questions/15002441/…
    • 我找到了问题所在。如果复合组件的 id 和 h:input 的 id 相同,则 p:outputLabel 将不起作用。
    • 不应为复合组件的子组件分配动态 ID,而应分配固定 ID。
    • 是的,这是根据您之前的回答完成的。但是,如果您在复合组件中使用固定 ID“franco”,并且在他内部的 inputText 中使用相同的固定 ID“franco”,这将不起作用。显然非常感谢@BalusC
    • 这很可能是&lt;p:outputLabel&gt; 中的一个错误。复合组件子组件的 ID 应该尽可能保持中立。例如。 id="input"。尽管如此,你还是最好创建一个标签文件而不是复合文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2016-10-31
    • 2012-12-12
    • 2013-12-16
    • 2012-05-08
    相关资源
    最近更新 更多