6 Replies Latest reply on Apr 17, 2007 3:53 PM by delphi'sghost

    Problems Starting Page Flows

    delphi'sghost

      I've been looking into pageflows and come across a number of oddities which, maybe I'm misunderstand the where's and whens of pageflows, but maybe someone has some insights.

      I have test.xml that contains a bunch of test links with the different ways of starting page flows :

      Using propagation and pageflow inline on an s:link
      Annotating the action method with @Begin(pageflow="TestFlow")
      A plain action method that starts a page flow manually


      Test.xhtml


       <s:link value="inline pageflow with xxx outcome" action="#{TestAction.stringFunc('xxx')}" propagation="begin" pageflow="TestFlow"/><br/>
       <s:link value="inline pageflow with 'page1' outcome" action="#{TestAction.stringFunc('page1')}" propagation="begin" pageflow="TestFlow"/><br/>
       <s:link value="inline pageflow with 'next' outcome" action="#{TestAction.stringFunc('next')}" propagation="begin" pageflow="TestFlow"/><br/>
       <s:link value="annotated pageflow with 'xxx' outcome" action="#{TestAction.annotatedStringFunc('xxx')}"/><br/>
       <s:link value="annotated pageflow with 'page1' outcome" action="#{TestAction.annotatedStringFunc('page1')}"/><br/>
       <s:link value="annotated pageflow with 'next' outcome" action="#{TestAction.annotatedStringFunc('next')}"/><br/>
       <s:link value="Manual PageFlow start in code" action="#{TestAction.manualStartFlow}"/><br/>
      
      


      My bean actions are listed below :

       public String manualStartFlow() {
       log.info("Manual StartFlow called");
       Pageflow.instance().begin("TestFlow");
       return "ManualStartFlow";
       }
      
      
       public String stringFunc(String input) {
       log.info("Called String Func with '#0'", input);
       return input;
       }
      
       @Begin(pageflow="TestFlow")
       public String annotatedStringFunc(String input) {
       log.info("Called annotated String Func with '#0'", input);
       return input;
       }
      
      


      I have added the page flow into the components.xml file and written the flow as follows :

      <?xml version="1.0"?>
      
      <pageflow-definition xmlns="http://jboss.com/products/seam/pageflow"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://jboss.com/products/seam/pageflow http://jboss.com/products/seam/pageflow-1.2.xsd"
       name="TestFlow">
      
      
       <start-page name="teststart" view-id="/testpage1.xhtml">
       <transition name="next" to="test2" />
       <transition name="ManualStartFlow" to="test2"/>
       <transition name="page1" to="test1"/>
       <redirect/>
       </start-page>
      
      
       <page name="test1" view-id="/testpage1.xhtml">
       <transition name="next" to="test2" />
       </page>
      
       <page name="test2" view-id="/testpage2.xhtml">
       <transition name="next" to="test3" />
       <transition name="prev" to="test1" />
       </page>
      
       <page name="test3" view-id="/testpage3.xhtml"
       no-conversation-view-id="/meetinglist.xhtml">
       <transition name="prev" to="test2" />
       </page>
      
      </pageflow-definition>
      


      Obviosuly, this is testing code which is why page 1 appears in the start-page and test1 page.

      The problem is that one of the following happens :

      The conversation, and page flow starts but there is no navigation to page 1. This usually happens when the outcome is 'xxx' from the string function.
      If I return "next" or "ManualStartFlow" as the outcome, I end up on page 2 of the flow
      If I return "page1" from the outcome I end up on page 1, probably because of the transition from start-page to page 'page1'.

      Once I am in the pages (testpage1,2 or 3) everything works fine, I just have problems starting the flow.

      In cases where I stay on the same page (test.xhtml) and I end up in a conversation and try to start a new one I obviously get the Seam Debug Page because of starting a conversation from an existing one (which is fine). On the debug page, I can see the list of conversations, and despite not navigating there, they all say testpage1.xhtml in the view id. This indicates to me that the conversation and flow is starting, it's just not navigating in cases where I return 'xxx' from the outcome of the methods.

      I would have thought that if you click a link, button, or call a method that starts a pageflow, then you would automatically end up on the view-id referenced by the start-page definition (in this case testpage1). Currently it looks like I need to return an outcome that will determine where you go automatically from the page-start view id, and not returning an expected outcome results in staying on the same page.

      Is that the case?

      DG

        • 1. Re: Problems Starting Page Flows
          pmuir

           

          "Delphi's Ghost" wrote:
          I have test.xml that contains a bunch of test links with the different ways of starting page flows :


          FYI, you can also use pages.xml to start pageflows (my favourite ;)

          I would have thought that if you click a link, button, or call a method that starts a pageflow, then you would automatically end up on the view-id referenced by the start-page definition (in this case testpage1).


          No. You use start-page when you are:

          already at the page being rendered


          If you want to navigate to a new view as a result of starting the pageflow, use a start-state node.

          But if the pageflow is begun as the result of an action listener invocation, the outcome of the action listener determines which is the first page to be rendered. In this case, we use a <start-state> as the first node in the pageflow, and declare a transition for each possible outcome:


          • 2. Re: Problems Starting Page Flows
            delphi'sghost

            Hey Peter, thanks for the reply.

            I changed my page flow to use :

             <start-state name="teststart">
             <transition to="test1"/>
             </start-state>
            
            
             <page name="test1" view-id="/testpage1.xhtml">
             <transition name="next" to="test2" />
             </page>
            


            and when I click my links I get :

            pageflow is not currently at a <page> or <start-page> node
            (note that pageflows that begin during the RENDER_RESPONSE phase should use <start-page> instead of <start-state>)


            Which I had already tried.

            So, I think most of my cases involve going to a new page when I start a flow, therefore, I need to use start-state, hence thereforth, I need to determine how to start a page flow that is compatable with the start-state syntax.

            After a bit of messing around, browsing the examples (DVD Store checkout flow) it looks like I have it working.

            (Steps included for the benefit of the next poor soul with this problem)

            I added a function which returns void, and annotate it with the begin(pageflow). I also added one without the annotation so I could test the inline pageflow/conversation starters :

             @Begin(pageflow="TestFlow")
             public void annotatedVoidFunc() {
             log.info("Annotated Voidfunc Called");
             }
            
             public void voidFunc() {
             log.info("Voidfunc Called");
             }
            
            


            In my page, I created new links :

            <s:link value="Annotated Void Func" action="#{TestAction.annotatedVoidFunc}"/><br/>
            <s:link value="inline Void Func" action="#{TestAction.voidFunc}" propagation="begin" pageflow="TestFlow"/><br/>
            


            I compiled, deployed, ran, and both links work fine.

            So, I guess if you want to jump to the first page of the pageflow and have navigation handled for you by the page flow, you need to use a void function that doesn't return a string.

            I have to confess, I am a little unclear on how action methods are handled when they return void vs returning null vs returning a string. From this example, it seems that it does make a difference.

            Thanks again peter,

            DG





            • 3. Re: Problems Starting Page Flows
              delphi'sghost

              Regarding pageflows from the pages.xml file, are you using the generic catch-all "*' view id and assigning outcomes to pageflows? i.e.

              <page view-id="*'>
              <navigation>
               <rule if-outcome="startWizard">
               <begin-conversation pageflow="wizardFlow"/>
               </rule>
              </navigation>
              </page>
              
              


              or do you put the begin-conversation tag on the "wizardPage1" page information :

              <page view-id="wizardPage1.xhtml">
               <begin-conversation pageflow="wizardFlow"/>
              </page>
              
              


              I'm just wondering since the first method allows global navigation based on the outcome of startWizard from any method. The second requires you to always navigate to the wizardPage1.xhtml page in order to start the wizard page flow. In the event of the name of first page page of the wizard changes, means you have to replace it everywhere.




              • 4. Re: Problems Starting Page Flows
                pmuir

                In an outcome other than null will cause the conversation((/pageflow) to start (null is to redisplay the current page). Void allows you to have no outcome, but with the conversation starting. The outcome you return from your action method on starting the pageflow should determine which transition it uses from the start-state - if you are sure it doesn't, raise an issue in JIRA

                • 5. Re: Problems Starting Page Flows
                  pmuir

                  I use the second model as it is RESTful - navigate to that page in your address bar and your pageflow starts - and I can't see how it requires more hard coding. Use a global outcome to navigate to that page...

                  When we get RHDS there should be refactoring support for this as well.

                  • 6. Re: Problems Starting Page Flows
                    delphi'sghost

                     

                    The outcome you return from your action method on starting the pageflow should determine which transition it uses from the start-state - if you are sure it doesn't, raise an issue in JIRA


                    AFAICT, when using the start-state pageflow the following applies :

                    void action methods start the pageflow on the first page (correct)
                    non-null outcomes with a matching transition in the start-state element results in making that transition and displaying the transitioned-to page(correct)
                    non-null outcomes without a matching transition in the start-state element results in re-displaying the current page.(don't know)
                    Null outcomes re-display the same page (correct)

                    Heh, you're right, you can use global outcome managers to navigate to that link AND get the benefit of RESTful URLs