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.

Here is the story I recounted. The summary is that you cannot update a composite component. You can only update a container within a composite component, which may have the same id as the component itself.

The malformedXML statement is the error sent by the catch block that surrounds the DOM update. I put a breakpoint there and discovered the underlying message:

"username not found"

So it wasn't able to find the id on the page to update. To give you context, here is the response XML:

<?xml version="1.0" encoding="utf-8"?>
<partial-response><changes><update id="username"><![CDATA[
  <div class="entry"><label for="username:input" class="label errors">
  Username:<span class="required">*</span></label>
  <span class="input errors"><input id="username:input" type="text" name="username:input" value="aa" onblur="mojarra.ab(this,event,'blur',0,'username')" />
 </span><span class="error errors">size must be between 3 and 15</span>
 </div>]]></update><update id="javax.faces.ViewState"><![CDATA[-3748785966430840586:-6352458055258675720]]></update></changes></partial-response>

As you can see, I have a div around my input (the client id of input is "input"). The div is defined by a composite component named p:edit as follows:

<p:edit id="username"><h:inputText id="input" value="..."/></p:edit>

The simplified template looks like:

<div class="entry">

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}">

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.

On Sat, May 23, 2009 at 1:26 PM, David Geary <clarity.training@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.




Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action


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.