[jsr-314-open] Ajax rendering of components among compositions?

David Geary clarity.training at GMAIL.COM
Sun May 24 17:51:08 EDT 2009


2009/5/24 Dan Allen <dan.j.allen at gmail.com>
> I think you are running into the "composite component gets an id in the
component tree but is not represented in the rendered output problem". I've
been
> discussing this problem in private mailings with Ryan and Andy...and now
that you have observed it too I think it is something we need to address.

I'm not sure if we are talking about the same thing. Here's my situation. I
have a menu with an image:

           <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="*image*"/>
                <f:selectItems value="#{places.zoomLevelItems}"/>

                <h:graphicImage id="progressbar" style="display: none"
                  library="images" name="orange-barber-pole.gif"/>
             </h:selectOneMenu>
           </h:panelGrid>

           <h:graphicImage id="*image*"
url="#{cc.parent.attrs.location.mapUrl}"
            style="border: thin solid gray"/>

See the attached 001.png to see what it looks like.

When the user changes the zoom level in the menu, the zoom index is updated
on the server, and when the ajax call returns, the image is updated due to
the render attribute of the <f:ajax> tag. That works fine (thanks, Ryan!).

Ok, so now I want to encapsulate the zoom prompt and menu in a composite
component, so I can just do this:

*           <places:zoomLevelControl/>
*
           <h:graphicImage id="image"
url="#{cc.parent.attrs.location.mapUrl}"
            style="border: thin solid gray"/>

Here's what that component looks like:

<!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:interface>

 <!-- IMPLEMENTATION -->
 <composite:implementation>
   <h:outputScript library="javascript/prototype"
name="prototype-1.6.0.2.js"/>
   <h:outputScript library="components/places" name="util.js"/>

   <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="image"/>
       <f:selectItems value="#{places.zoomLevelItems}"/>

       <h:graphicImage id="progressbar" style="display: none"
         library="images" name="orange-barber-pole.gif"/>

     </h:selectOneMenu>
   </h:panelGrid>

 </composite:implementation>
</html>

All I've done is cut the zoom prompt and menu from the original file, and
pasted it into zoomLevelControl.xhtml.

However, now when I change the zoom level menu, I get an error:

    <f:ajax> contains an unknown id 'image'

If I remove the <f:ajax> tag from places:zoomLevelControl.xhtml, so the page
can load without an error, there is actually a component whose id is image
(at least relative to the naming container in which it resides). Here's the
HTML:

<img
id="form:j_id1186681689_16ef8569:0:j_id1186681689_16ef8513:j_id-1105909415_41ead6fe:
*image*" src="
http://gws.maps.yahoo.com/mapimage?MAPDATA=2Y3iJ.d6wXVASQ9jSqfHLeKEax1dy5SAHJNemUUlZBYuvpfIWQ9MKbXJ.SoEDpCUAAQYuF9hQvb7E.gRWJG90677SNjMOa.AbNyqN.J66qv_y8Mo0DU60U9Nph2E4lfj63DVp9y5MGYMeBiSzuKOhRs-&amp;mvt=m&amp;cltype=onnetwork&amp;.intl=us&amp;appid=gaspe_geary&amp;oper=&amp;_proxy=ydn%2Cxml"
style="border: thin solid gray" />


>> The problem is, while the username id is represented in the tree (as the
>> composite component), it's not represented in the rendered output. The
>> composite component is a non-rendering container. That's why the update
>> script cannot locate the DOM node to update.
>>
>> To get it to work, I had to represent the id of the component template
>> somewhere in my template...most naturally on the wrapping div.
>>
>> <div class="entry" id="#{cc.clientId}">
>>   <comp:insertChildren/>
>> </div>
>>
>
I wasn't able to get something like that to work for my situation.


>> Is this an unwritten rule? Or should the id automatically be assigned to
>> the first child of the composite component. I can see people getting easily
>> confused over this.
>
>
> Developers are going to trip all over this subtlety, I'm sure of it.
>

Oh yeah, absolutely. I'm certain that refactoring an ajaxified composite
component in the manner I've described above will be a common occurrence.
I'm not sure what the underlying technical reasons are for not being able to
do that refactoring, but IMO, it's got to work, or composite components will
loose much of their value.


david


> On Sat, May 23, 2009 at 1:26 PM, David Geary <clarity.training at gmail.com>wrote:
>
>> I have a view composed of a template, and a handful of compositions. In
>> one of those compositions, I want to trigger an ajax request with f:ajax,
>> and I want to render a component in a different composition (but ultimately
>> in the same page). That doesn't seem to work.
>>
>> To be a little more explicit, I have a menu, implemented with a
>> composition, from which I launch an ajax request. When the request returns,
>> I want to render a single component in another composition. However, when I
>> try to do that, JSF complains that the component id cannot be found, when in
>> fact, the component is in the page, and is even in the same naming
>> container.
>>
>> I suspect that f:ajax is looking for the component id before the page is
>> fully constructed, and therefore only sees components in the same
>> composition.
>>
>> This should work, correct? If I cannot effectively use ajax across
>> compositions in the same page, then that makes templating a lot less
>> attractive.
>>
>> Thanks,
>>
>>
>> david
>>
>
> -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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jsr-314-open-mirror/attachments/20090524/571d638d/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 001.png
Type: image/png
Size: 36459 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/jsr-314-open-mirror/attachments/20090524/571d638d/attachment.png 


More information about the jsr-314-open-mirror mailing list