[jsr-314-open-mirror] [jsr-314-open] Ajax inside a DataTable

Andy Schwartz andy.schwartz at oracle.com
Wed May 19 10:48:45 EDT 2010


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-ReevaluateComponentReferencingMechanismP2

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




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