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

Reply via email to