Conditionally rendered input component does not update value

jsfjsf-2primefaces

Using jsf 2 and Primefaces 3.4

I am aware that there are many similar questions but none of them work on this one.

When the panelGrid "inner" is rendered with a fixed value of "true" (<h:panelGrid id="inner" rendered="true">)
=> after the commandbutton is clicked the input component updates correctly the value of #{tableMatchesBean.mergedAuthorAjax},

but when the rendering of this panel is conditional: <h:panelGrid rendered="#{spellCheckBean.renderInputMerge}">
=> then the input component is silent (no trace that tableMatchesBean.mergedAuthorAjax has been invoked).

Note: I used the nested panelGrids to put the render condition in a parent element of the component that need to be conditionally rendered (the output and input components). Any help appreciated.

[EDIT after comment:] What the xhtml page does:
– when the user clicks on the "merge" option in the selectOnebutton, an ajax update toggles the "renderInputMerge" to true which causes the "outer" component to be displayed. It works fine. In this component, there is an input field, which is displayed OK.
– after the user clicks on the commandLink button, I need to retrieve the value of this input field. As explained above, I have a problem with that.

The xhtml:

<h:body style ="width:100%">


    <h:form id = "currMatch">

        <h:panelGrid>

            <p:selectOneButton id ="selection" value="#{spellCheckBean.optionChosen}">
                <f:selectItem itemLabel="keep both" itemValue="1" />
                <f:selectItem itemLabel="delete both" itemValue="2" />
                <f:selectItem itemLabel="merge" itemValue="3" />
                <p:ajax update="outer" />
            </p:selectOneButton>

        </h:panelGrid>

         <h:panelGrid id="outer" >
            <h:panelGrid id="inner" rendered="#{spellCheckBean.renderInputMerge}">
            <!-- **the line above does not update**, this one does    <h:panelGrid rendered="true">-->

                <h:outputText value="our suggestion:  "  style ="margin-left: auto; margin-right: auto"/> 
                     <h:inputText id ="testinput" value="#{tableMatchesBean.mergedAuthorAjax}">
                     </h:inputText>
                </h:panelGrid>    
        </h:panelGrid>

        <p:commandButton action="#{tableMatchesBean.next_()}" 
                         title="Add"
                         value="next"
                         update ="currMatch"
                         >

        </p:commandButton>




    </h:form>
</h:body>

Best Answer

Your rendered condition apparently depends on a request scoped variabe, e.g. a property of a request scoped managed bean or a request parameter. A form submit accounts as a completely independent and brand new request whrein all request scoped managed beans are newly recreated, with all properties set to default. If the rendered attribute evaluates to false during collecting the submitted values (the apply request values phase of the form submit), then they simply won't be collected.

There are basically 2 ways to solve this:

  1. Make sure that the condition behind the rendered attribute is properly preinitialized in the (post)constructor of the request scoped bean so that it returns exactly the same value during the request of processing the form submit as it was during the request of displaying the form to the enduser.

  2. Put the bean in the view scope instead. This way the bean instance will live as long as you're interacting with the same view by ajax or by returning void or null in action method.

See also:

Related Topic