0

I've got a form in a view, for example say:

form.xhtml

<h:form>
    <h:panelGrid columns="2">
        <h:outputLabel value="Name" />
        <h:inputText value="#{bean.name}" />

        <h:outputLabel value="Age" />
        <h:inputText value="#{bean.age}"
                     converter="#{ageConverter}" />

        <h:outputLabel value="" />
        <h:commandButton action="#{bean.submit}"
                         value="Submit" />
    </h:panelGrid>
</h:form>

Supported by the following bean:

Bean.java

@Named
// Scope
public class Bean implements Serializable {
    @Inject private Service service;

    private String name;
    private int age;
    private List<Person> people;

    public void submit() {
        people= service.getPeople(name, age);
    }

    // getters & setters for name & age
    // getter for people
}

Resulting in a view for people:

result.xhtml

<h:form>
    <h:dataTable value="#{bean.people}"
                 var="person">
        <h:column>
            <f:facet name="header">Name</f:facet>
            #{person.name}
        </h:column>

        <h:column>
            <f:facet name="header">Day of Birth</f:facet>
            #{person.dayOfBirth}
        </h:column>
    </h:dataTable>
</h:form>

Now obviously the use-case is similar to: - Submit the form using form.xhtml - Get people from service using Bean.java - Show people using result.xhtml

In this example there's still a small part of the puzzle incomplete. For example the scope is decisive in whether or not there are people at all in the result, furthermore there's no forward (or anything similar) to the resulting page.

Now I'm not sure in what would be the best (or at least a good) way to accomplish this. Here are some ways I've been able to think of:

  • Using @ViewScoped (JSF2.2) and implicit navigation (returning a String from submit()) to navigate to the second page. However this breaks the viewscope (anyway to accomplish this)?
  • Using @ViewScoped and include the right file (form.xhtml or result.xhtml) based on rendered='' with some EL. This could be done with an Ajax-call on the submit.
  • Passing the values name and age as GET-parameters on a request to result.xhtml and executing the logic on a @PostConstruct (though, what if the form is 'huge')? In this case @RequestScoped would suffice.

My question is, what would be an efficient and good (best) way to accomplish this usecase?

Thanks for your input.

Menno
  • 12,175
  • 14
  • 56
  • 88

2 Answers2

2

I think what you are looking for is flash scope. It survives a redirect but it's not available anymore in subsequent requests.

A solution would be to pass your name and age variables via the flash scope, and use them to render your results.

wjans
  • 10,009
  • 5
  • 32
  • 43
  • Yeah, but it seems I forgot to mention I'm using CDI. An alternative would be to use Conversation scope but how can I destroy this scope in case someone navigates away from the form instead of finishing the usecase? – Menno May 18 '13 at 09:39
  • +1 since your suggestion for flash scope pointed me to the actual CDI-solution `@FlowScoped` as mentioned in my example. – Menno May 18 '13 at 09:55
  • @Aquillo, you can handle conversation scope management in a CDI bean-based JSF app with a [custom navigation handler](http://stackoverflow.com/a/15441777/1530938) – kolossus May 18 '13 at 17:32
1

It seems JSF 2.2 hasn't just provided us with @ViewScoped, it also has provided us with @FlowScoped. For more info: documentation. This seems to fit the requirements nicely.

Menno
  • 12,175
  • 14
  • 56
  • 88