0

Is it possible to combine the new JSF 2.2 Faces Flow feature with Ajax?

Use case: There is a wizard embedded in a panel on a page. As the user steps through the wizard, only the panel shall be updated, not the entire page.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Harald Wellmann
  • 12,615
  • 4
  • 41
  • 63

3 Answers3

1

I am looking down this route myself and did some research. Short answer is Yes you can use ajax for both partial view processing and partial view rendering. Here is a working example:

Flow Definition

@ApplicationScoped
public class MyFlow implements Serializable {

    @Produces @FlowDefinition
    public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {
        flowBuilder.id("", "myFlow");
        flowBuilder.viewNode("flowP1", "/flowPage1.xhtml").markAsStartNode();
        return flowBuilder.getFlow();
    }
}

flowPage1.xhtml (first and only view in the flow):

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>View within Flow Ajax test</title>
</h:head>
<h:body>
    <h:form>
        <h:panelGrid columns="2">
            <p:commandButton value="Flow Action Method" action="#{myFlowBean.flowActionMethod}" update="flowText"/>
            <p:commandButton value="View Action Method" action="#{myViewBean.viewActionMethod}" update="viewText"/>
            <h:outputText id="flowText" value="#{myFlowBean.flowValue}" />
            <h:outputText id="viewText" value="#{myViewBean.viewValue}" />
        </h:panelGrid>
    </h:form>
</h:body>
</html>

Backing Beans

Flow-Scoped Bean

@Named
@FlowScoped("myFlow")
public class MyFlowBean implements Serializable{

    private String flowValue;

    @PostConstruct
    public void init(){
        System.out.println("MyFlowBean PostConstruct");
    }

    public void flowActionMethod(){
        System.out.println("flowActionMethod called");
        //flowValue = "Flow Value Set";
    }

    public String getFlowValue() {
        return flowValue;
    }

    public void setFlowValue(String flowValue){
        this.flowValue = flowValue;
    }
}

View-Scoped Bean

@Named
@ViewScoped
public class MyViewBean implements Serializable {

    private @Inject MyFlowBean flowBean;
    private String viewValue;

    @PostConstruct
    public void init(){
        System.out.println("MyViewBean PostConstruct");
    }

    public void viewActionMethod(){
        System.out.println("viewActionMethod called");
        viewValue = "View Value Set";
        flowBean.setFlowValue("Flow Value Set");
    }

    public String getViewValue() {
        return viewValue;
    }
}

Navigate to the Flow using "myFlow" as a navigation-case from anywhere outside the flow. Once flowPage1.xhtml has rendered, do the following to demonstrate AJAX usage:

  1. Press "View Action Method" button. This will set the value of both bean fields, but only render the view-scoped field. So you will only see the text for the view-scoped field.
  2. Press "Flow Action Method" button. This will render the Flow scoped bean field, displaying the value that was already set by the View bean's action method.
jdessey
  • 690
  • 6
  • 14
0

Check out this basic explanation about Faces Flow:

Faces Flow provides an encapsulation of related views/pages with an application defined entry and exit points. For example, a check out cart can consist of cart page, credit card details page, shipping address page, and confirmation page. All these pages, along with required resources and beans, can be packaged together as a module which can then be reused in other applications.

Personally I haven't tried it yet, however being it an encapsulation of views, makes sense you'll not have the chance to use Ajax for flow transitions.

A view in JSF 2.x is designed to keep alive as long as its controller (backing bean) behind it doesn't return a new outcome value. However the flow itself defines a combination of outcomes which you'll allow in your application. The only way to use Ajax is not destroying the view you already have, but the flow does it for every single transition.

To achieve what you want you should implement your tutorial using a single @ViewScoped backing bean and only a jsf view page with rendering conditionals into it.

Community
  • 1
  • 1
Aritz
  • 30,971
  • 16
  • 136
  • 217
0

I have see guys on liferay project use (recomand) this feature to manage wizard base portlets

http://www.liferay.com/web/neil.griffin/blog/-/blogs/three-cheers-for-jsf-2-2-faces-flows

Alireza Fattahi
  • 42,517
  • 14
  • 123
  • 173