2009/5/24 Jim Driscoll <Jim.Driscoll@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">
   
   <!-- 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.