Search code examples
ajaxjsf-2

Component ID in ui:repeat problems


I'm trying to render a grandparent component. The code:

<h:form prependId="false>
<h:panelGroup id="outer_panel">
    <ui:repeat var="curr" value="#{bean.map}">
        <h:panelGroup id="inner_panel">
            <h:commandButton value="Remove" action="actionThing" >
                <f:ajax render="outer_panel" />
            </h:commandButton>
        </h:panelGroup>
    </ui:repeat>
</h:panelGroup>
</h:form>

I get an exception:

javax.faces.FacesException: Component with id:outer_panel not found

Tried to add the index to the id, which didn't work neither:

<h:form prependId="false>
<h:panelGroup id="outer_panel">
    <ui:repeat var="curr" value="#{bean.map}" varStatus="loop">
        <h:panelGroup id="inner_panel">
            <h:commandButton value="Remove" action="actionThing" >
                <f:ajax render="#{loop.index+1}:outer_panel" />
            </h:commandButton>
        </h:panelGroup>
    </ui:repeat>
</h:panelGroup>
</h:form>

Any idea why the ID is not found?

Thanks.


Solution

  • It is not found because you used a relative client ID in render attribute. It becomes relative to the closest parent naming container component. In this case, that's the <ui:repeat> (it prepends generated client ID of the children with the row index). So the component with ID outer_panel has to be inside the <ui:repeat> in order to get it to work. However, the outer_panel is actually outside it.

    You need to specify an absolute client ID instead of a relative client ID. To make it absolute (so that it will basically scan from the view root on), prefix the client ID with :.

    <f:ajax render=":outer_panel" />
    

    For the case that you didn't use prependId="false" on the <h:form>, then you should have used

    <f:ajax render=":form_id:outer_panel" />
    

    instead.