0

I'm having problems updating an inner nested h:panelGroup element using f:ajax. I have minimized my problem into following example:

<h:form id="someForm">
    <h:panelGroup id="wrapper">
        <h:panelGroup id="content">
            Some Content
        </h:panelGroup>
    </h:panelGroup>

    <h:commandLink
        action="#{bean.changeContent()}"
        value="Do Something">
        <f:ajax render=":someForm:wrapper:content"/>
    </h:commandLink>
</h:form>

When i try to open the page, the findComponent method throws an IllegalArgumentException with no further information:

Severe:   Error Rendering View[/view/group/invitation/testCase.xhtml] 
   java.lang.IllegalArgumentException: wrapper
at javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:655)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getResolvedId(AjaxBehaviorRenderer.java:302)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.appendIds(AjaxBehaviorRenderer.java:292)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.buildAjaxCommand(AjaxBehaviorRenderer.java:225)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getScript(AjaxBehaviorRenderer.java:89)
...

I looked into the implementation and found following section that was causing the Exception:

...
result = findComponent(base, segments[i], (i == 0));
// the first element of the expression may match base.id
// (vs. a child if of base)
if (i == 0 && result == null && segments[i].equals(base.getId())) {
    result = base;
}
if (result != null && (!(result instanceof NamingContainer)) && length > 0) {
    throw new IllegalArgumentException(segments[i]);
}
...

I debugged the program, the component is found (by the first line of the code above), so my only conclusion is that h:panelGroup is not an instance of NamingContainer, but after reading this post and checking the generated HTML for other examples my understanding was that a h:panelGroup IS a naming container. However, when i remove the wrapper and tell the ajax element to update the content panelGroup directly, no exception is thrown. I probably don't fully understand the method that JSF uses to search through the elements, I'd appreciate it if someone could explain to me why this tiny example behaves this way. I am using Mojarra 2.2.0 on GlassFish 4.0

Community
  • 1
  • 1
bmurauer
  • 989
  • 8
  • 24
  • *"and checking the generated HTML for other examples my understanding was that a h:panelGroup IS a naming container"* can you elaborate more how you came up to this conclusion? This is namely wrong. – BalusC Jul 14 '15 at 09:14
  • i thought so because the rendered HTML contained an element with its id="someForm:content" and thought that the "content" part was rendered because it was a named container. However, then the "wrapper" part should have been rendered too, of course. I now understand how it works, thanks – bmurauer Jul 14 '15 at 09:31

1 Answers1

2

When you want to update/render a component from same h:form you don't need to attach the form id to component id.
So in you case

<f:ajax render="content"/> 

would do the job for you.

And h:panelGroup is not a NamingContainer component. So you dont need to refer the inner components of h:panelGroup by nesting its id.

So <h:panelGroup id="content"> can be referred from out side form with just someForm:content.
someForm:wrapper:content is wrong thing. This is the reason you are getting the exception.

You can always find out the generated component id on browser by Right Click and Inpect element.

Kishor Prakash
  • 8,011
  • 12
  • 61
  • 92
  • Thanks! i was confused that i could specify a h:panelGroup for an ajax update although it is not a naming container. Everythings is working now. – bmurauer Jul 14 '15 at 09:28