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 jsf.ajax.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