0

Setup: I have 2 forms A & B I have a commandLink in form A:

<h:commandLink actionListener="#{homeView.selectDiv('homeUpdates')}">#{msg.homeUpdates}
   <f:ajax render=":B" execute="@this" />
</h:commandLink>

...which updates form B.

The problem is that when I click the ajax link, it rebuilds form A as well and gets an exception from a ui:repeat I have. Is this correct behaviour? Should it rebuild form A as well?

I am using JSF 2.2 and form A contains a ui:fragment=>ui:include=>ui:repeat

=====Added SSCCE======= The following code does not run after pressing Update B! twice. It gives an exception of duplicate id. The value for ui:repeat is irrelevant

<h:head>
</h:head>

<h:body>
    <h:form id="A">
        <ul class="tableView notification">
            <ui:repeat var="notification" value="#{dashboardBean.notifications}">
                <li>
                    xx
                </li>
            </ui:repeat>
        </ul>

        <h:commandLink value="Update B!" listener="#{dashboardBean.toggleRendered}">
            <f:ajax execute="@this" render=":B" />
        </h:commandLink>

    </h:form>

    <h:form id="B">
    </h:form>
</h:body>
Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48
  • Extra hint: If I modify render to -":A :B" then the error goes away. It appears that for some reason, the 'execute' triggers a rebuilt of the form and for some other weird reason it add ui:repeat again (with the same id), which gives me the following error: Component ID navigation_form:uif1 has already been found in the view. – Ioannis Deligiannis Apr 26 '13 at 13:00

1 Answers1

1

Upon initial request the view is created, upon postbacks the view is restored. To recite some points of JSF 2.2 specification for clarity (emphasis mine):

P. 2.2.1:

If the request is not a postback ... call createView() on the ViewHandler. If the request is a postback, ... call ViewHandler.restoreView(), passing the FacesContext instance for the current request and the view identifier, and returning a UIViewRoot for the restored view.

P. 2.5.8:

Selected components in a JSF view can be priocessed (known as partial processing) and selected components can be rendered to the client (known as partial rendering).

P. 13.4:

The JavaServer Faces lifecycle, can be viewed as consisting of an execute phase and a render phase. Partial traversal is the technique that can be used to “visit” one or more components in the view, potentially to have them pass through the “execute” and/or “render” phases of the request processing lifecycle.

When you use AJAX, PartialViewContext class will contain all the information that's needed to traverse the restored view.


So, to get back to your question, under <f:ajax render=":B" execute="@this" /> setup, only the form with id="B" will be rerendered, which implies <h:form id="B">, no form nestings, etc.

Regarding your 'doesn't work' comment the simple test case with a plain view scoped managed bean gave me the expected results:

<h:form id="A" >
    <h:outputText value="#{twoFormsBean.a}"/>
    <h:commandLink actionListener="#{twoFormsBean.actionA}">
        Update B!
        <f:ajax execute="@this" render=":B"/>
    </h:commandLink>
</h:form>
<h:form id="B" >
    <h:outputText value="#{twoFormsBean.b}"/>
    <h:commandLink>
        Update Both!
        <f:ajax execute="@this" render=":A :B"/>
    </h:commandLink>
</h:form>

with

@ManagedBean
@ViewScoped
public class TwoFormsBean implements Serializable {

    private String a = "A";//getter
    private String b = "B";//getter

    public void actionA(ActionEvent ae) {
        a = "newA";
        b = "newB";
    }

}
skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • Your answer is aligned with my expectations on how it should work, so thank you for compiled details. I managed to identify the critical/breaking factor which is that in form A I have a composite component(defined as an .xhtml under WebContent/resources/components). If I remove this from within the ui:repeat everything works at it should. When I put it back it breaks.
    – Ioannis Deligiannis Apr 26 '13 at 13:39
  • You need to provide for a SSCCE so that we'd be able to reproduce your problem. And welcome! – skuntsel Apr 26 '13 at 13:40
  • Restore view in case of Facelets builds the view again from scratch and then applies the view state (if any). – Mike Braun Apr 28 '13 at 15:58