2

I'm trying to update an element within an UI-repeat, but unfortunately I still haven't discovered how to correctly address the outputPanel from within the dataTable. I am aware that this problem comes from the different naming containers, nevertheless, I hope there will be a solution.

<h:body>
    <h:form id="form">
        <ui:repeat var="_entry" value="#{test.entries}">
            <p:outputPanel id="counterPanel">
                <h:outputText value="#{test.counter}" />
            </p:outputPanel>

            <p:dataTable var="_p" id="paramTable" value="#{_entry.params}">
                <p:column headerText="Options">
                    <p:commandLink value="Update" update="counterPanel"  />
                </p:column>
            </p:dataTable>
        </ui:repeat>
    </h:form>
</h:body>

The code example above raises the following exception:

javax.servlet.ServletException: Cannot find component with identifier "counterPanel" in view.

Thx, Jakob

jkob
  • 43
  • 2
  • 4
  • Can you see in the generated html source what id the outputpanel has? And maybe post it here? – roel Mar 14 '12 at 10:58

1 Answers1

5

Two ways:

  1. You need to give the <ui:repeat> a client ID so that you can refer it by the absolute client ID path:

    <h:form id="form">
        <ui:repeat id="entries" var="_entry" value="#{test.entries}">
            <p:outputPanel id="counterPanel">
                <h:outputText value="#{test.counter}" />
            </p:outputPanel>
    
            <p:dataTable var="_p" id="paramTable" value="#{_entry.params}">
                <p:column headerText="Options">
                    <p:commandLink value="Update" update=":form:entries:counterPanel" />
                </p:column>
            </p:dataTable>
        </ui:repeat>
    </h:form>
    
  2. Move the <h:form> to inside the outer loop so that you can use @form:

    <ui:repeat var="_entry" value="#{test.entries}">
        <h:form id="form">
            <p:outputPanel id="counterPanel">
                <h:outputText value="#{test.counter}" />
            </p:outputPanel>
    
            <p:dataTable var="_p" id="paramTable" value="#{_entry.params}">
                <p:column headerText="Options">
                    <p:commandLink value="Update" update="@form" />
                </p:column>
            </p:dataTable>
        </h:form>
    </ui:repeat>
    
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Recently I came across the approch to get the id of a naming container with a kind of bottom-up-approach: #{component.parent.parent.clientID}. However this was tricky because not all components will be rendered (a composite component naming container for instance). What is your opinion? – Matt Handy Mar 14 '12 at 12:03
  • 1
    @Matt: This is particularly useful inside composites, but not necessarily in normal templates. I'd only use `#{component.namingContainer.clientId}` to get the client ID of the closest parent naming container component or `#{component.namingContainer.parent.namingContainer.clientId}` to get the client ID of the second parent naming container component, etcetera. Note that this won't work when the naming container is by itself a repeating component. It would return a client ID with the row index suffixed which would result in "component not found" as the row index only exist at client side. – BalusC Mar 14 '12 at 12:06
  • Related answer: http://stackoverflow.com/questions/8847096/get-id-of-parent-naming-container-in-template-for-in-render-update-attribute/8850963#8850963 – BalusC Mar 14 '12 at 12:07
  • This is exactly what we experienced. Thanks for the advice. – Matt Handy Mar 14 '12 at 12:09