stackisfull
stackisfull

Reputation: 1

How to address components inside dynamic repeat inside a composite component

Got some difficulties addressing components inside ui:repeat iterating over a collection which is a attribute of a composite component like so:

<ui:component>
    <cc:interface>
        <cc:attribute name="dummyList" />
    </cc:interface>

    <cc:implementation>
        <div id="#{cc.clientId}">
            <ui:repeat id="repeat" value="#{cc.attrs.dummyList}" var="d">
                <p:outputPanel>
                    <h:outputText id="repeat-item" value="#{component.clientId} / #{testBean.state}"/>
                </p:outputPanel>
            </ui:repeat>
        </div>
    </cc:implementation>
</ui:component>

This does not work:

<p:commandButton value="Increment (component)"
                 action="#{testBean.incrementState()}"
                 process="@this"
                 update="form:testComp:repeat:0:repeat-item"/>

<comb:testComp id="testComp" dummyList="#{testBean.dummyList}"/>

Error: org.primefaces.expression.ComponentNotFoundException: Cannot find component for expression "form:testComp:repeat:0:repeat-item" referenced from "form:incrementBtn".

Following constellations work without problems:

<p:commandButton id="incrementBtn"
                 value="Increment"
                 action="#{testBean.incrementState()}"
                 process="@this"
                 update="form:repeat:0:repeat-item"/>

<ui:repeat id="repeat" value="#{testBean.dummyList}" var="d">
    <p:outputPanel>
        <h:outputText id="repeat-item" value="#{component.clientId} / #{testBean.state}"/>
    </p:outputPanel>
</ui:repeat>
<ui:component>
    <cc:implementation>
        <div id="#{cc.clientId}">
            <ui:repeat id="repeat" value="#{testBean.dummyList}" var="d">
                <p:outputPanel>
                    <h:outputText id="repeat-item" value="#{component.clientId} / #{testBean.state}"/>
                </p:outputPanel>
            </ui:repeat>
        </div>
    </cc:implementation>
</ui:component>
<p:commandButton id="incrementBtn" value="Increment (component)"
                 action="#{testBean.incrementState()}"
                 process="@this"
                 update="form:testComp:repeat:0:repeat-item"/>

<comb:testComp id="testComp"/>
<comb:testComp id="testComp" dummyList="#{testBean.dummyList}"/>

<p:commandButton id="incrementBtn" value="Increment (component)"
                 action="#{testBean.incrementState()}"
                 process="@this"
                 update="form:testComp:repeat:0:repeat-item"/>

My real use case is to update a specific panel inside a repeat inside a composite component from a button in a dialog. There I get the same error.

While debugging and playing around with different ideas and solutions I stumbled over the behaviour described above.

Note: "form" is the id of an outer form element.

Because interestingly this (without specifying "form:") also does not work:

<comb:testComp id="testComp" dummyList="#{testBean.dummyList}"/>

<p:commandButton id="incrementBtn" value="Increment (component)"
                 action="#{testBean.incrementState()}"
                 process="@this"
                 update="testComp:repeat:0:repeat-item"/>

Error: org.primefaces.expression.ComponentNotFoundException: Cannot find component for expression "testComp:repeat:0:repeat-item" referenced from "form:incrementBtn".

Upvotes: 0

Views: 32

Answers (1)

stackisfull
stackisfull

Reputation: 1

Here is the slightly more complex example with dialog:

<comb:testComp id="testComp" dummyList="#{testBean.dummyList}"/>

<p:dialog id="testDlg" widgetVar="testDlg" dynamic="true">

  <p:commandButton id="incrementBtn" value="Increment (component)"
                   action="#{testBean.incrementState()}"
                   process="@this"
                   update="#{testBean.panelId}"/>
</p:dialog>
<ui:component>
    <cc:interface>
        <cc:attribute name="dummyList" />
    </cc:interface>

    <cc:implementation>
        <div id="#{cc.clientId}">
            <ui:repeat id="repeat" value="#{cc.attrs.dummyList}" var="d">
                <p:outputPanel id="repeatPanel">
                    <h:outputText id="repeat-item" value="#{component.clientId} / #{testBean.state}"/>

                    <p:commandButton id="openDlgBtn" value="Open dialog"
                                     action="#{testBean.prepareDialog(component.parent.clientId)}"
                                     process="@this"
                                     update="form:testDlg"/>
                </p:outputPanel>
            </ui:repeat>
        </div>
    </cc:implementation>
</ui:component>
    public void prepareDialog(String panelId) {
        this.panelId = panelId;
        PrimeFaces.current().executeScript("PF('testDlg').show()");
    }

Error when trying to open the dialog: org.primefaces.expression.ComponentNotFoundException: Cannot find component for expression "form:testComp:repeat:1:repeatPanel" referenced from "form:incrementBtn".

It only works with dynamic=false in dialog.

Again it feels like there must be a connection between the order of statements and evaluation of the composite component attributes.

Upvotes: 0

Related Questions