0
votes

I need your help..., please...

I'm in the middle of a migration process from JSF 1.2 to JSF 2.1.

The Implementation I use is Sun's Mojarra implementation with facelets, which in JSF 1.2 were not part of the standard but, since JSF 2.0 they become.

Right now I am using javax.faces.PARTIAL_STATE_SAVING as true. (Tried with false, but none of my custom components worked.)

We have some custom JSF components, and in most cases they are working fine. However, the following example is not working correctly:

<ui:repeat value="#{myBean.list}" var="item">            
       <tr style="cursor:pointer;">   
             <td class="texttable col_med col15Personal">   
                    <bf:TextBox   
                           compId="aliasName"  
                           value="#{item.aliasName}"  
                           compStyle="font-size:1em;"    
                           maxLength="15" showAutoLabel="false"/>   
             </td>   
       </tr>   
</ui:repeat>  

bf:TextBox is a custom text box which extends HtmlPanelGroup and has 2 custom children components:

A custom label (extending HtmlOutputlabel) and aa custom input(extending HtmlInputText)

When this component is used without ui:repeat, everything works fine. However when inside it, problems occur.

In the first renderreponse phase, everything is fine. But when you do a post, in the restoreview phase, the children of the custom HtmlPanelGroup (label and inputText) are not present in the viewRoot, so the values submitted are not present.

The same code snipped was working in the JSF 1.2 correctly.

I know that there are alternatives to ui:repeat (example c:forEach), but since I'm working on a migration process it's really complex to change all code involving this type mentioned.

Thank you all in advance,

1

1 Answers

1
votes

I have found a workaround for my issue. As the main goal was to make minimum changes into application... I avoided changing the all pages that were using ui:repeat. Instead, I have changed my custom component to save the children into State Holder (saveState method) and then I restore the children if the component has a ui:repeat as parent.

if (getInsideUIRepeat() != null && getInsideUIRepeat().booleanValue()) {  
            values[42] = this.getChildren();  
        }  

this is extracted from saveState method.

 if (getInsideUIRepeat() != null && getInsideUIRepeat().booleanValue()) {  
           List<UIComponent> children = (List<UIComponent>) values[42];  
            if (children != null) {  
                this.getChildren().clear();  
                this.getChildren().addAll(children);  
            }  
        }  

this is extracted from restoreState method.

private boolean hasUIRepeatAsParent() {  
    UIComponent parent = this.getParent();  
    while (parent != null) {  
        if (parent instanceof UIRepeat) {  
            return true;  
        }  
        parent = parent.getParent();  
    }  
    return false;  
}  

this is the method that checks if component has UIRepeat as parent

Thank you all again...