I have an application that displays maps at different zoom levels. (If you're interested in a visual, see http://www.ibm.com/developerworks/java/library/j-jsf2fu1/index.html, and please vote for 5 stars. :))

Anyway, my view code is pretty simple:

  <h:selectOneMenu id="menu" onchange="submit()"
                  value="#{place.zoomIndex}"
                  valueChangeListener="#{place.zoomChanged}">
    
    <f:selectItems value="#{places.zoomLevelItems}"/>
              
  </h:selectOneMenu>

  <h:graphicImage id="image" url="#{cc.parent.attrs.thePlace.mapUrl}"/>

As you can tell from #{cc.parent.attrs...} this code is in a composite component, that itself resides in another composite component. The preceeding code works just fine. When I select a different zoom level, the surrounding form is submitted, my value change listener is invoked, which sets the zoom level in my place backing bean, and subsequently, when the request returns, place.getMapUrl() returns a map at the appropriate zoom level.

However, with the preceeding code, the entire page redraws when I change the zoom level. I figured it'd be a snap to use f:ajax to just update the image, so I removed the onchange attribute, and added an f:ajax tag to the body of h:selectOneMenu, like this:

<h:selectOneMenu id="menu"
                  value="#{place.zoomIndex}"
                  valueChangeListener="#{place.zoomChanged}"
                  style="font-size:13px;font-family:Palatino">
    
  <f:selectItems value="#{places.zoomLevelItems}"/>
  <f:ajax execute="@this" render="image"/>
              
</h:selectOneMenu>

With FireBug, I've verified that a POST request is indeed executed when I change the zoom level, and it appears that everything is in order:

form    form
j_id-939329235_16ef8569:0:j_id-939329235_16ef8513:j_id1608935764_5fe6690f:menu    3
javax.faces.ViewState    -1363564553004911965:-1863826268811277742
javax.faces.behavior.event    valueChange
javax.faces.partial.ajax    true
javax.faces.partial.event    change
javax.faces.partial.execute    j_id-939329235_16ef8569:0:j_id-939329235_16ef8513:j_id1608935764_5fe6690f:menu
javax.faces.partial.render    j_id-939329235_16ef8569:0:j_id-939329235_16ef8513:j_id1608935764_5fe6690f:image
javax.faces.source    j_id-939329235_16ef8569:0:j_id-939329235_16ef8513:j_id1608935764_5fe6690f:menu

I get a response back that looks like this:

  <?xml version="1.0" encoding="utf-8"?>
  <partial-response><changes><update id="javax.faces.ViewState"><![CDATA[1747337848471748955:2683565346534242854
  ]]></update></changes></partial-response>

However, with f:ajax, my value change listener is never invoked on the server, so the menu doesn't update, even though I've specified that the menu should go through the execute phase of the lifecycle.

Does anyone know why my value change listener is not invoked? Am I doing something wrong, or is this a bug?

btw, here are a couple of interesting datapoints:

1. I have breakpoints in jsf.ajax.request and jsfajax.response. The request breakpoint is hit, but the response is not. The return status for the response is 200, so there are apparently no errors.

2. I thought, from Jim Driscoll's blog about f:ajax, that we had to specify client ids for execute and render, so I originally had this:

  <f:ajax execute="@this" render="#{cc.clientId}:image"/>

But when I do that, I get this error...

  <f:ajax> contains an unknown id 'j_id-939329235_16ef8569:0:j_id-939329235_16ef8513:j_id1608935764_5fe6690f:image'

...when I load the page, even though that is the correct client id (as evidenced from the request data above). Evidently, we're supposed to use the component id and not the client id?

I'm trying to put together a demo for JavaOne, so if anyone can give me some insights, I'd be most grateful.

Thanks,


david