4
votes

I'm migrating from RichFaces 3.3.3 to 4.0, and have come across a problem that can't figure out how to solve.

Until now, I've used RichFaces'@KeepAlive annotation to achieve View scope with beans, but new version 4 doesn't have such feature (as far as I know) so far. So I thought the @ViewScoped annotation would be the natural (and quick) replacement, but it's not working. Here's the relevant code that is giving me trouble. It renders a table containing the customers with their names as links, so when a name is clicked it raises a popup to edit the data. It works in v3.3.3 with @KeepAlive, but does not in v4 with @ViewScoped (popup doesn't get called).

The page:

<h:form prependId="false">
 <rich:dataTable id="table" value="#{myBean.customers}" var="customer">
    <!--...headers...-->
    <h:column>
        <a4j:commandLink action="#{myBean.selectCustomer}"
            oncomplete="#{rich:component('popup_customer_editor')}.show();" render="form_customer_editor">
            ${customer.name}
            <f:setPropertyActionListener value="#{customer}" target="#{myBean.selectedCustomer}"/>
        </a4j:commandLink>
    </h:column>
    <h:column>${customer.address}</h:column>
 </rich:dataTable>
</h:form>

<rich:popupPanel id="popup_customer_editor>
    <h:form id="form_customer_editor">
    <!--...form fields...-->
    </h:form>
</rich:popupPanel>

The bean:

@ManagedBean
@ViewScoped   //It was @KeepAlive before
public class MyBean implements Serializable
{
    private String name;
    private String address;
    private Customer selectedCustomer;  //POJO class
    //getters and setters
    ...
    public String selectCustomer()
    {
        name = selectedCustomer.getName();
        address = selectedCustomer.getAddress();

        return null;
    }
}

Any help would be appreciated

1

1 Answers

3
votes

There are two reasons why your action might not be called:

  1. You have a field that is submitted and the validation/convertion fails. Your action will not be invoked if you have validation or conversion errors. You should have a <h:messages> to be sure you see it, and since it's a4j:clickLink put it inside an a4j:outputPanel like this: <a4j:outputPanel ajaxRendered="true"><h:messages/></a4j:outputPanel>.

  2. You have an <h:form> inside another <h:form>, and you're trying to submit the inner one. You can track this with firebug really-really easy. JSF decides not to do anything at all for some reason.

It looks like you're doing some funky business in here:

  1. re-render forms. I had serious issues with rerendering <h:form>s in JSF2 (namely they stop working), esp. with richfaces modal panel, made posible by the way they implement the actual panel, where they move the content from wherever it is in the DOM in the <body> element. Thus I recommend to create an <h:panelGrid> inside the form, and re-render that one.
  2. <f:setPropertyActionListener>. Really? You should have EL2 as well, so you could change this:

    <a4j:commandLink action="#{myBean.selectCustomer}"
        oncomplete="#{rich:component('popup_customer_editor')}.show();"
        render="form_customer_editor">
             ${customer.name}
        <f:setPropertyActionListener value="#{customer}"
            target="#{myBean.selectedCustomer}"/>
    </a4j:commandLink>
    

to

<a4j:commandLink action="#{myBean.selectCustomer(customer)}"
    oncomplete="#{rich:component('popup_customer_editor')}.show();" render="form_customer_editor" value=#{customer.name}"/>