Hey Cagatay -
On 5/19/10 4:20 AM, Cagatay Civici wrote:
Hi,
I've faced with an issue in our app I'd like to share when trying to
update the datatable itself from a command element located inside a
column. Case is to select a row, execute logic and update the
datatable. Basic code:
<h:dataTable id="cars" var="car"
value="#{tableBean.carsSmall}">
<h:column>
<f:facet name="header">
Model
</f:facet>
<h:outputText value="#{car.model}" />
</h:column>
<h:column>
<f:facet name="header">
Action
</f:facet>
<h:commandButton value="Some Action"
actionListener="#{tableBean.handleRowAction(car)}">
<f:ajax render="cars" />
</h:commandButton>
</h:column>
</h:dataTable>
As datatable has a rowIndex >= 0 during rendering of commandButton
f:ajax defines the component id to render as cars:{rowIndex} where I
should expect "cars" only. This is due to UIData.getClientId
implementation as UIData
adds rowIndex for unique row ids. This causes an issue with a nested
f:ajax case.
Ids specified by <f:ajax> are relative to containing component - in this
case, relative to the <h:commandButton>. This makes is easy to
specify execute/render ids for components within the same
NamingContainer (which is by far the most common case). In the case of
iterating components like <h:dataTable> or <ui:repeat>, this means that
execute/render ids refer to components within the same row.
There is a way out of this... You can specify an absolute id by
prefixing the id with ":". At that point the id starts from the root of
the component tree and you can specify any number of colon-separated
segments to descend into each naming container. (This matches the
syntax used by findComponent().)
Of course, specifying absolute paths is at a minimum difficult, and in
some cases, just plain impossible to do (eg. when reusing content across
multiple pages). In Trinidad we use a double-colon prefix ("::") to
reference up one level in the NamingContainer hierarchy - similar to
".." in file system paths. I suggested exposing this when we were
working on the <f:ajax> spec, but this topic got shelved until 2.1.
Dan has captured some of our thinking here:
http://seamframework.org/Documentation/JSF21#H-ReevaluateComponentReferen...
More here:
http://seamframework.org/Documentation/JSFEnhancementComponentReferencing
Oh, and... for the particular use case that you describe above, I think
that it is very important that the JSF implementations give some warning
when a referenced component is not found, at least when running in
development project stage. Not sure which implementation you are
testing, but it might make sense to log bugs against MyFaces/Mojarra if
this is failing silently in development mode.
Andy
Regards,
Cagatay Civici