丢失在复合组件中提交的输入

时间:2012-10-31 20:12:04

标签: jsf primefaces submit composite-component

我在提交复合组件时遇到问题。

我的大多数复合组件都包含输入组件和“提交”按钮。 当我试图将按钮保持在相同的h:form但不在同一个复合组件中时,提交的值似乎在某处“丢失”了。并且,例如,我的验证器被调用原始值。

示例:

<composite:interface>
  <composite:attribute name="titreContext" required="true"/>
</composite:interface>
<composite:implementation>

    <p:outputPanel id="selectionTitreDetailsPanel" styleClass="selectionTitreDetails">
    <p:outputPanel id="selectionTitreDetailsPanelInner" rendered="#{not empty cc.attrs.titreContext.selected}">

    <p:panelGrid columns="2" id="panelId">
      <h:outputText id="idLabel" value="Id :"/>
      <h:outputText id="id" value="#{cc.attrs.titreContext.selected.titeluid}"/>
      <p:tooltip for="id" value="Identifiant unique"/>
    </p:panelGrid>

    <p:panelGrid columns="2" id="titelePanel">
        <p:outputLabel for="selectTitele" value="Titre :"/>
        <p:selectOneMenu id="selectTitele" value="#{cc.attrs.titreContext.selected.titele}" effect="fold" styleClass="fullWidth">
            <f:selectItems value="#{constants.getTitelesForTypman(cc.attrs.titreContext.selected.titele.typman)}" var="titele" itemLabel="#{titele.titelelil}" itemValue="#{titele}" styleClass="fullWidth"/>
                <p:column styleClass="fullWidth">#{titele.titelelil}</p:column>
        </p:selectOneMenu>      
    </p:panelGrid>

    [...]
    <p:commandButton id="confirmerModifications" icon="small_edit" type="submit" value="Confirmer les modifications" 
                    action="#{elutersEditionContext.confirmeModifsSelection}" process="mandatsTerritorial" 
                    update="mandatsTerritorial #{cc.attrs.notifUpdates}"/>

</composite:implementation>

作品。

但是将p:commandButton放在复合词之外:

<h:form>
<mylib:mycomponent /*parameters *//>
<p:commandButton /*parameters*/ />
</h:form>

不起作用。当我调试验证器时,我可以看到修改后的值甚至没有提交。 getLocalValue,getSubmittedValue和getValue都没有改变。

复合组件声明中是否有语法用于纠正这种情况? 顺便说一下:当我将我的组件编写为复合组件而不是自定义组件时,检索辅助bean中的#{asen}就行了。

提前致谢。

我正在使用:

  • PrimeFaces 3.4.1
  • CODI 1.0.5
  • OpenWebBeans 1.1.6
  • MyFaces 2.1.9
  • Tomcat 7.0.32

(更新)这个非常奇怪的问题是由h:form nesting引起的。

非常奇怪,因为h:表单嵌套不会扰乱第一级复合组件的处理,但会在嵌套合成中导致这种奇怪的“输入丢失”。

嵌套看起来像这样:

<h:form>
...
    <p:tabView ...>
        <p:tab>
        <h:form>
            <my:composite ....>
        </h:form>
    </p:tabView>
</h:form>

1 个答案:

答案 0 :(得分:2)

您在process的{​​{1}}属性中使用了相对客户ID:

<p:commandButton>

相对客户端ID相对于父NamingContainer组件。它将作为<p:commandButton ... process="mandatsTerritorial" /> 组件的直接子项进行搜索。如果孩子本身是NamingContainer,则不会搜查其子女。

复合组件本身实际上也是NamingContainer个组件。如果按钮放在合成中,则会将其作为NamingContainer直接子项进行搜索。在您的特定情况下,只有具有<cc:implementation>的组件将在表单提交时处理,包括其所有子项(请注意,此组件在到目前为止发布的代码中无处可见,但我想您省略了它为简洁起见)。

如果按钮位于id="mandatsTerritorial",则会将其作为<h:form>直接子项进行搜索。然而,由于这显然被放置在复合材料内(如上所述,另一个<h:form>组件),它将无法找到,因此基本上不会处理任何内容。您需要修复NamingContainer以指向正确的客户端ID。 E.g。

process

通过这种方式,它将处理自身(强制调用操作!)以及<h:form> <mylib:mycomponent id="mycomponent" /> <p:commandButton ... process="@this mycomponent:mandatsTerritorial" /> </h:form> 内具有id="mandatsTerritorial"的{​​{1}}组件{。}}。

作为一个完全不同的替代方案,在这个特定的构造中可以正常工作,就是完全删除<cc:implementation>属性。它默认为id="mycomponent",因此将处理整个表单。


根据您的问题更新

更新:嵌套表单在HTML中无效。使用JSF process表示不会改变这种情况;你仍然会在HTML中使用嵌套表单。未指定浏览器行为将提交给服务器的数据。确保您不在JavaScript中嵌套@form