[ 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

Reply via email to