jsfviewreusabilityjsf-2.2faces-flow

Faces flow with reusable views


Each example I've seen for Faces Flow involves exclusive views that are only used within the particular flow. What I would like to do is create a flow that consists almost entirely of views that will be used in more than one flow, and/or potentially outside of a flow. Is this reusability of views possible, or were Faces Flows not meant to be used this way?

Faces Flow example from JavaEE 7 doc


Solution

  • Faces Flow is basically composed (or can be) by JSF views, being themselves reusable. If you refer to this post:

    What's new in JSF 2.2 for flows ?

    The flow of application is no longer restricted to flow between pages but instead defined as flow between "nodes". There are five different types of nodes:

    View: Any JSF page in the application

    Method Call: Invoke application logic from flow graph via an EL

    Switch: Navigation decisions in the flow graph based on boolean EL

    Flow Call: Call another flow with parameters and receive return values

    Flow Return: Return to the calling flow

    The first point itself answers your question!


    EDIT FROM OP (@jdessey)

    I've confirmed the accepted answer in testing, and wanted to share a few caveats in implementation.

    Programmatic flow definition (i.e. @FlowDefinition annotation) is only processed if the class that contains the annotated method is itself a normal scoped CDI bean such as `@ApplicationScoped`. (Might be a bug - I'm using JSF 2.2.4 and Weld 2.0.4)
    When defining the view node using FlowBuilder.viewNode(String viewNodeId, String vdlDocumentId), the document id must be the absolute path to the .xhtml file. This is in the javadoc but not intuitive IMO because since 2.0 we are used to implicit navigation.
    

    Code:

    @ApplicationScoped
    public class MyFlow implements Serializable {
    
        @Produces @FlowDefinition
        public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {
            flowBuilder.id("", "myFlow");
            flowBuilder.viewNode("anyView", "/absolutePathToView.xhtml").markAsStartNode();
            return flowBuilder.getFlow();
        }
    }
    

    Now to navigate to this flow, just use "myFlow" as an implicit navigation case such as:

    <p:menuitem value="Begin Flow" action="myFlow" />