You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Mathias Werlitz (JIRA)" <my...@incubator.apache.org> on 2005/06/21 14:14:17 UTC

[jira] Created: (MYFACES-288) DataTable: Facets Bug

DataTable: Facets Bug
---------------------

         Key: MYFACES-288
         URL: http://issues.apache.org/jira/browse/MYFACES-288
     Project: MyFaces
        Type: Bug
    Versions: 1.0.9 beta    
    Reporter: Mathias Werlitz
    Priority: Blocker


There seems to be a big bug in the dataTable component implementation.
If you use two dataTable components within each other the facets of the inner table do not work correctly.
For example if you use a inputText component in the footer (of the inner table) the value is not updated an no valueChangeListener is notified.

Here an example:

<f:view>
<html>
    <body>
    <h:form>
    <h:dataTable id="outer" value="#{test}" var="outeritem">
        <h:column>
                <h:dataTable id="inner" value="#{outeritem}"  var="item" >
		.....
            
           		 <f:facet name="header">
                            		<h:inputText id="myinput" valueChangeListener="#{testBean.listener}" />
                	</f:facet>
        	</h:dataTable>
        </h:column>
    </h:dataTable>  
    </h:form>
    </body>
</html>
</f:view>

I have found one solution, but I'm not sure if it is the right way:

The funkctions to save the childState for the nested UIData have to be fixed in javax.faces.component.UIData:



private void restoreDescendantComponentStates(
		FacesContext context,
		UIComponent component,
		boolean saveState)
	{
		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
		{
			UIComponent child = (UIComponent) i.next();
			//clear this descendant's clientId:
			child.setId(child.getId());
			//HACK: This assumes that setId always clears the cached clientId. Can we be sure?

			if (saveState)
			{
				//see saveDescendantComponentStates(UIComponent)
				if (child instanceof UIData)
				{
					UIData childUIData = (UIData) child;
					Object state =
						_rowState._clientIdsToChildUIDataStates.get(
							childUIData.getClientId(context));
					if (state == null)
					{
						UIDataRowState initialState =
							(UIDataRowState) _rowState._clientIdsToChildUIDataStates.get(getInitialClientId(context, child));

						if (initialState == null)
						{
							throw new IllegalStateException(
								"No initial state defined for clientId: " + child.getClientId(context));
						}

						state = new UIDataRowState(initialState);
					}



					childUIData._rowState = (UIDataRowState) state;
					childUIData.restoreDescendantComponentStates(context, childUIData, true); // fix
					
					restoreDescendantComponentStates(context, component, false);
					continue;
				}

				if (!_firstTimeRendered && child instanceof EditableValueHolder)
				{
					EditableValueHolder childEVH = (EditableValueHolder) child;
					Object state =
						_rowState._clientIdsToChildEVHStates.get(child.getClientId(context));
					if (state == null)
					{
						state =
							_rowState._clientIdsToChildEVHStates.get(
								getInitialClientId(context, child));
					}
					((EditableValueHolderState) state).restore(childEVH);
					
				}
			}

			restoreDescendantComponentStates(context, child, saveState);
		}
	}



private void saveDescendantComponentStates(FacesContext context, UIComponent component)
	{
		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
		{
			//TODO: what if child is an EditableValueHolder AND a UIData?

			UIComponent child = (UIComponent) i.next();
			if (child instanceof UIData)
			{
				
				UIData childUIData = (UIData) child;
				childUIData.saveDescendantComponentStates(context, childUIData); // fix
				_rowState._clientIdsToChildUIDataStates.put(
					childUIData.getClientId(context),
					childUIData._rowState);
				continue;
			}

			if (child instanceof EditableValueHolder)
			{
				EditableValueHolder childEVH = (EditableValueHolder) child;
				_rowState._clientIdsToChildEVHStates.put(
					child.getClientId(context),
					new EditableValueHolderState(childEVH));
			}

			saveDescendantComponentStates(context, child);
		}
	}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (MYFACES-288) DataTable: Facets Bug

Posted by "Mathias Werlitz (JIRA)" <my...@incubator.apache.org>.
    [ http://issues.apache.org/jira/browse/MYFACES-288?page=comments#action_12315255 ] 

Mathias Werlitz commented on MYFACES-288:
-----------------------------------------

The bug seems to resolved with the patch for UIData of Mathias Broekelmann for MYFACES-228

> DataTable: Facets Bug
> ---------------------
>
>          Key: MYFACES-288
>          URL: http://issues.apache.org/jira/browse/MYFACES-288
>      Project: MyFaces
>         Type: Bug
>     Versions: 1.0.9 beta
>     Reporter: Mathias Werlitz
>     Priority: Blocker

>
> There seems to be a big bug in the dataTable component implementation.
> If you use two dataTable components within each other the facets of the inner table do not work correctly.
> For example if you use a inputText component in the footer (of the inner table) the value is not updated an no valueChangeListener is notified.
> Here an example:
> <f:view>
> <html>
>     <body>
>     <h:form>
>     <h:dataTable id="outer" value="#{test}" var="outeritem">
>         <h:column>
>                 <h:dataTable id="inner" value="#{outeritem}"  var="item" >
> 		.....
>             
>            		 <f:facet name="header">
>                             		<h:inputText id="myinput" valueChangeListener="#{testBean.listener}" />
>                 	</f:facet>
>         	</h:dataTable>
>         </h:column>
>     </h:dataTable>  
>     </h:form>
>     </body>
> </html>
> </f:view>
> I have found one solution, but I'm not sure if it is the right way:
> The funkctions to save the childState for the nested UIData have to be fixed in javax.faces.component.UIData:
> private void restoreDescendantComponentStates(
> 		FacesContext context,
> 		UIComponent component,
> 		boolean saveState)
> 	{
> 		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
> 		{
> 			UIComponent child = (UIComponent) i.next();
> 			//clear this descendant's clientId:
> 			child.setId(child.getId());
> 			//HACK: This assumes that setId always clears the cached clientId. Can we be sure?
> 			if (saveState)
> 			{
> 				//see saveDescendantComponentStates(UIComponent)
> 				if (child instanceof UIData)
> 				{
> 					UIData childUIData = (UIData) child;
> 					Object state =
> 						_rowState._clientIdsToChildUIDataStates.get(
> 							childUIData.getClientId(context));
> 					if (state == null)
> 					{
> 						UIDataRowState initialState =
> 							(UIDataRowState) _rowState._clientIdsToChildUIDataStates.get(getInitialClientId(context, child));
> 						if (initialState == null)
> 						{
> 							throw new IllegalStateException(
> 								"No initial state defined for clientId: " + child.getClientId(context));
> 						}
> 						state = new UIDataRowState(initialState);
> 					}
> 					childUIData._rowState = (UIDataRowState) state;
> 					childUIData.restoreDescendantComponentStates(context, childUIData, true); // fix
> 					
> 					restoreDescendantComponentStates(context, component, false);
> 					continue;
> 				}
> 				if (!_firstTimeRendered && child instanceof EditableValueHolder)
> 				{
> 					EditableValueHolder childEVH = (EditableValueHolder) child;
> 					Object state =
> 						_rowState._clientIdsToChildEVHStates.get(child.getClientId(context));
> 					if (state == null)
> 					{
> 						state =
> 							_rowState._clientIdsToChildEVHStates.get(
> 								getInitialClientId(context, child));
> 					}
> 					((EditableValueHolderState) state).restore(childEVH);
> 					
> 				}
> 			}
> 			restoreDescendantComponentStates(context, child, saveState);
> 		}
> 	}
> private void saveDescendantComponentStates(FacesContext context, UIComponent component)
> 	{
> 		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
> 		{
> 			//TODO: what if child is an EditableValueHolder AND a UIData?
> 			UIComponent child = (UIComponent) i.next();
> 			if (child instanceof UIData)
> 			{
> 				
> 				UIData childUIData = (UIData) child;
> 				childUIData.saveDescendantComponentStates(context, childUIData); // fix
> 				_rowState._clientIdsToChildUIDataStates.put(
> 					childUIData.getClientId(context),
> 					childUIData._rowState);
> 				continue;
> 			}
> 			if (child instanceof EditableValueHolder)
> 			{
> 				EditableValueHolder childEVH = (EditableValueHolder) child;
> 				_rowState._clientIdsToChildEVHStates.put(
> 					child.getClientId(context),
> 					new EditableValueHolderState(childEVH));
> 			}
> 			saveDescendantComponentStates(context, child);
> 		}
> 	}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Closed: (MYFACES-288) DataTable: Facets Bug

Posted by "sean schofield (JIRA)" <my...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/MYFACES-288?page=all ]
     
sean schofield closed MYFACES-288:
----------------------------------

    Fix Version: Nightly Build
     Resolution: Fixed

> DataTable: Facets Bug
> ---------------------
>
>          Key: MYFACES-288
>          URL: http://issues.apache.org/jira/browse/MYFACES-288
>      Project: MyFaces
>         Type: Bug
>     Versions: 1.0.9 beta
>     Reporter: Mathias Werlitz
>     Priority: Blocker
>      Fix For: Nightly Build

>
> There seems to be a big bug in the dataTable component implementation.
> If you use two dataTable components within each other the facets of the inner table do not work correctly.
> For example if you use a inputText component in the footer (of the inner table) the value is not updated an no valueChangeListener is notified.
> Here an example:
> <f:view>
> <html>
>     <body>
>     <h:form>
>     <h:dataTable id="outer" value="#{test}" var="outeritem">
>         <h:column>
>                 <h:dataTable id="inner" value="#{outeritem}"  var="item" >
> 		.....
>             
>            		 <f:facet name="header">
>                             		<h:inputText id="myinput" valueChangeListener="#{testBean.listener}" />
>                 	</f:facet>
>         	</h:dataTable>
>         </h:column>
>     </h:dataTable>  
>     </h:form>
>     </body>
> </html>
> </f:view>
> I have found one solution, but I'm not sure if it is the right way:
> The funkctions to save the childState for the nested UIData have to be fixed in javax.faces.component.UIData:
> private void restoreDescendantComponentStates(
> 		FacesContext context,
> 		UIComponent component,
> 		boolean saveState)
> 	{
> 		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
> 		{
> 			UIComponent child = (UIComponent) i.next();
> 			//clear this descendant's clientId:
> 			child.setId(child.getId());
> 			//HACK: This assumes that setId always clears the cached clientId. Can we be sure?
> 			if (saveState)
> 			{
> 				//see saveDescendantComponentStates(UIComponent)
> 				if (child instanceof UIData)
> 				{
> 					UIData childUIData = (UIData) child;
> 					Object state =
> 						_rowState._clientIdsToChildUIDataStates.get(
> 							childUIData.getClientId(context));
> 					if (state == null)
> 					{
> 						UIDataRowState initialState =
> 							(UIDataRowState) _rowState._clientIdsToChildUIDataStates.get(getInitialClientId(context, child));
> 						if (initialState == null)
> 						{
> 							throw new IllegalStateException(
> 								"No initial state defined for clientId: " + child.getClientId(context));
> 						}
> 						state = new UIDataRowState(initialState);
> 					}
> 					childUIData._rowState = (UIDataRowState) state;
> 					childUIData.restoreDescendantComponentStates(context, childUIData, true); // fix
> 					
> 					restoreDescendantComponentStates(context, component, false);
> 					continue;
> 				}
> 				if (!_firstTimeRendered && child instanceof EditableValueHolder)
> 				{
> 					EditableValueHolder childEVH = (EditableValueHolder) child;
> 					Object state =
> 						_rowState._clientIdsToChildEVHStates.get(child.getClientId(context));
> 					if (state == null)
> 					{
> 						state =
> 							_rowState._clientIdsToChildEVHStates.get(
> 								getInitialClientId(context, child));
> 					}
> 					((EditableValueHolderState) state).restore(childEVH);
> 					
> 				}
> 			}
> 			restoreDescendantComponentStates(context, child, saveState);
> 		}
> 	}
> private void saveDescendantComponentStates(FacesContext context, UIComponent component)
> 	{
> 		for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
> 		{
> 			//TODO: what if child is an EditableValueHolder AND a UIData?
> 			UIComponent child = (UIComponent) i.next();
> 			if (child instanceof UIData)
> 			{
> 				
> 				UIData childUIData = (UIData) child;
> 				childUIData.saveDescendantComponentStates(context, childUIData); // fix
> 				_rowState._clientIdsToChildUIDataStates.put(
> 					childUIData.getClientId(context),
> 					childUIData._rowState);
> 				continue;
> 			}
> 			if (child instanceof EditableValueHolder)
> 			{
> 				EditableValueHolder childEVH = (EditableValueHolder) child;
> 				_rowState._clientIdsToChildEVHStates.put(
> 					child.getClientId(context),
> 					new EditableValueHolderState(childEVH));
> 			}
> 			saveDescendantComponentStates(context, child);
> 		}
> 	}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira