2009/5/24 Jim Driscoll <Jim.Driscoll(a)sun.com>
The only bizzare bit is where the absolute id didn't work - but
that's
explainable in a few ways.
The basic technique - using #{cc.clientId}:subcomponentid to reference the
rendered id in the ajax calls, does not seem excessively hard to me.
Agreed.
If you're doing ajax stuff in page, you need to know what the rendered id's
are going to be. The minute you start doing anything past hello
world, you
will anyway.
If you disagree with this, having seen the basic demo, then obviously I'm
wrong, since I'd say you're both more sophisticated than the target
audience. So please check that out (jsf-demo/ajax-switchlist), and let me
know.
Okay, I've done that, and I understand how to use component ids with ajax
(at least I think so), but something's not working for me. Check this out.
Sorry for the long listings, but I want to show everything. You can pretty
much just look at the bold text.
I have a composite component, map.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:places="http://java.sun.com/jsf/composite/components/places&qu...
<!-- INTERFACE -->
<composite:interface>
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<h:outputScript library="javascript/prototype"
name="prototype-1.6.0.2.js"/>
<h:outputScript library="components/places"
name="util.js"/>
<div class="map" id="mapDiv">
<div style="padding-bottom: 10px;">
<h:outputText value="#{cc.attrs.title}"
style="color: blue"/>
</div>
<h:panelGrid id="grid" columns="1">
<h:panelGroup id="group">
<div style="padding-left: 5px;">
<i>
<h:outputText
value="#{cc.parent.attrs.location.streetAddress},"/>
</i>
<h:outputText value=" #{cc.parent.attrs.location.city}, "
/>
<h:outputText value="#{cc.parent.attrs.location.state}"/>
<hr/>
</div>
</h:panelGroup>
* <places:mapZoomControl/>
*
<h:graphicImage id="*image*"
url="#{cc.parent.attrs.location.mapUrl}"
style="border: thin solid gray"/>
</h:panelGrid>
</div>
</composite:implementation>
</html>
The pertinent thing is that I'm using <places:mapZoomControl/>. In that
component, I have an <f:ajax> tag in a menu that should render the image
beneath <places:mapZoomControl>. That mapZoomControl component looks like
this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<composite:interface>
<composite:attribute name="ccId"/>
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<h:outputScript library="javascript/prototype"
name="prototype-1.6.0.2.js"/>
<h:outputScript library="components/places" name="util.js"/>
<div id="#{cc.clientId}">
<h:panelGrid columns="2">
<div class="zoomPrompt">
#{msgs.zoomPrompt}
</div>
<h:selectOneMenu id="menu"
value="#{cc.parent.attrs.location.zoomIndex}"
style="font-size:13px;font-family:Palatino">
* <f:ajax render="#{cc.parent.clientId}:image"/>
* <f:selectItems value="#{places.zoomLevelItems}"/>
<h:graphicImage id="progressbar" style="display: none"
library="images" name="orange-barber-pole.gif"/>
</h:selectOneMenu>
</h:panelGrid>
</div>
</composite:implementation>
</html>
Notice the <f:ajax> tag. I think I'm accessing the image from the parent
component (map.xhtml) correctly. However, when I load the page I get this:
<f:ajax> contains an unknown id
'form:j_id1186681689_16ef8569:0:j_id1186681689_16ef8513:j_id-1105909415_41ead6fe:image'
If I remove the f:ajax tag, load the page, and check the source, I see an
<img> tag:
<img
id="form:j_id1186681689_16ef8569:0:j_id1186681689_16ef8513:j_id-1105909415_41ead6fe:image"
src="..."/>
And that id is *exactly* what <f:ajax> says it cannot find. It's in the
page, but <f:ajax> cannot find it?!?
My guess is that <f:ajax> is evaluating the id before the page is completely
constructed, and therefore, it doesn't find it, but that's just a WAG on my
part.
So, if this is not correct:
<f:ajax render="#{cc.parent.clientId}:image"/>
Then how do I access the image in the parent (map) component?
It seems to me that I'm using <f:ajax> correctly, but I'd be happy to be
told otherwise.
Thanks,
david
Jim
On 5/24/09 7:09 PM, Dan Allen wrote:
> Hmmm, that seems really bizarre. Perhaps this is a bug in Mojarra but
> some chance. Could you distill this down to a basic use case and see if
> Ryan et al can make it a test in Mojarra. If there is a problem with the
> API, then it will be more clearly revealed.
>
>
> Frankly, for JSF 2.1, I would like to see us go to an XPath-like
> syntax (or jQuery) to find components because component IDs in
> JSF just plain suck.
>
>
> Yup, I agree wholeheartedly, but we need to make it easy to do Ajax
> rendering across composite components for JSF 2.0. IMO, composite
> components are by far the single most kickass feature of JSF 2, and
> if they're crippled, we're gonna get some bad press.
>
>
> No doubt. We definitely can't overlook the foreground problem here.
>
> -Dan
>
> --
> Dan Allen
> Senior Software Engineer, Red Hat | Author of Seam in Action
>
>
http://mojavelinux.com
>
http://mojavelinux.com/seaminaction
>
http://in.relation.to/Bloggers/Dan
>
> NOTE: While I make a strong effort to keep up with my email on a daily
> basis, personal or other work matters can sometimes keep me away
> from my email. If you contact me, but don't hear back for more than a
> week,
> it is very likely that I am excessively backlogged or the message was
> caught in the spam filters. Please don't hesitate to resend a message if
> you feel that it did not reach my attention.
>