]
Brian Leathem updated RF-11134:
-------------------------------
Labels: jsf (was: )
ComponentIdResolver does not resolve clientId correctly
-------------------------------------------------------
Key: RF-11134
URL:
https://issues.jboss.org/browse/RF-11134
Project: RichFaces
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: component-tables, core
Affects Versions: 4.0.0.Final
Reporter: Val Blant
Labels: jsf
Fix For: 5-Tracking
Attachments: richfaces-ajax-fix.js
Please consider the following test code:
{code}
<rich:dataTable id="testTable"
value="#{dataTableTestBackingBean.rowsModel}"
var="rowVar">
<f:facet name="header">
<rich:column>
<h:outputText value="Column 1" />
</rich:column>
</f:facet>
<rich:column>
<h:inputText id="valTest" value="#{rowVar.col1}" >
<a4j:ajax
event="blur"
render="testColumn, footerTest"
limitRender="true"
execute="@this" />
</h:inputText>
</rich:column>
<rich:column>
<h:outputText id="testColumn"
value="#{dataTableTestBackingBean.footerValue}" />
</rich:column>
<f:facet name="footer">
<rich:column>
<h:outputText id="footerTest"
value="#{dataTableTestBackingBean.footerValue}" />
</rich:column>
</f:facet>
</rich:dataTable>
{code}
This example will fail with the following Javascript error in the browser:
{color:red}
{quote}
Error: During update: formId:testTable:0:footerTest not found
{quote}
{color}
This is expected, b/c the correct id for the footer is _formId:testTable:footerTest_.
The bug is in _org.richfaces.context.ComponentIdResolver_. Here is what happens:
# The _RenderComponentCallback_ is executed on the input component (_'valTest'_
in the example) and it reads the list of short ids to render from the attached Ajax
Behavior. Note that we got here by walking the parent data table model, so the current
rowKey is 0
# _RenderComponentCallback_ asks _ComponentIdResolver_ to resolve short ids into client
IDs
# _ComponentIdResolver_ starts ascending up the tree from _'valTest'_ and looking
at facets and children until it finds _'footerTest'_.
# At this point it asks for the clientId of _'footerTest'_ w/o regard for the
fact that the data model has a rowKey that is set 0
So, we get the wrong id b/c we call UiData.getClientId() outside of the normal walking
order of that model.
*EDIT:*
I noticed that if I nest the above data table in another data iterator, then the footer
update suddenly starts working. I investigated and it turned out that nested table will
have _getClientId()_ called on all of its components by the parent table, and since
_clientId_ s are cached, by the time _ComponentIdResolver_ gets to it, it will use the
cached id, rather than looking it up at the wrong time. Non-nested tables simply don't
get around to calling _getClientId()_ on their components before _ComponentIdResolver_
runs, which is probably the real problem.
Could it be an issue with the way _UIDataAdapter.saveChildState(FacesContext
facesContext)_ is written? Note that a nested table would save the state of its facets in
_saveChildState(FacesContext facesContext, UIComponent component)_, which would result in
calls to _getClientId()_ on the facet cells. A top level table would not save the state of
the facets though, b/c we only traverse the children of the table inside
_UIDataAdapter.saveChildState(FacesContext facesContext)_
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: