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">
<comp:insertChildren/>
</div>
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>
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(a)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.