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