[richfaces-issues] [JBoss JIRA] Updated: (RF-11134) ComponentIdResolver does not resolve clientId correctly

Val Blant (JIRA) jira-events at lists.jboss.org
Fri Jul 15 22:01:23 EDT 2011


     [ https://issues.jboss.org/browse/RF-11134?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Val Blant updated RF-11134:
---------------------------

    Description: 
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.

  was:
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.
</b>



> 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) 
>    Affects Versions: 4.0.0.Final
>            Reporter: Val Blant
>
> 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.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the richfaces-issues mailing list