4 Replies Latest reply on Oct 29, 2009 4:37 PM by Acceleanu Dan

    Return to "previous" view, or... current view - 1

    Bob Corcoran Newbie

      We are making use of the seam events org.jboss.seam.notLoggedIn and org.jboss.seam.postAuthenticate to capture the current view and return to it when authentication is required. We also have several pages on our site that a user can view without being logged in. The user could be on a partuicular page and then decide to log in as opposed to being forced to log in. So the user clicks the login link in the header and at that point the current view becomes the login page. We would like to redirect the user to the previous view id after a successful log in, that is, the page the user was on before she clicked the log in link. I've looked through the code in the Redirect, Page, and a couple of other classes, and there doesn't appear to be a way to do this that is built into Seam. Would this be a good place for us to write an interceptor that captures the view the user was on at the time the log in link was clicked?

        • 1. Re: Return to "previous" view, or... current view - 1
          Luke Simon Newbie

          I try to do this with the breadcrumb class in Seam, but didn't work for me on 2.0.2.
          So I wrote my breadcrumb class as statefull bean and every navigation actions pass through it.
          It's weird...but...hey it's Seam! :-D

          • 2. Re: Return to "previous" view, or... current view - 1
            Bob Corcoran Newbie
            So far, I've accomplished redirecting to the previous page after login by putting this line under every page view id (except login page view) in pages.xml:

            <page view-id="/viewScores.xhtml">
                        <action execute="#{redirect.captureCurrentView}"/>
            ...

            and also having the following node in components.xml

            <event type="org.jboss.seam.postAuthenticate">
                   <action execute="#{redirect.returnToCapturedView}"/>
            </event>

            But I'm still looking to see if I can centralize <action execute="#{redirect.captureCurrentView}"/> in one place, maybe by raising a home grown event or writng an interceptor...




            • 3. Re: Return to "previous" view, or... current view - 1
              Stuart Douglas Master

              I do something like this in each conversation. I have a class, PageViewStack:



              /**
               * This allows for views the be accessed from various places and still return to
               * the correct parent view when the user is done with them, which having to pass
               * around parent view id as a page paramter. It is controlled from
               * WEB-INF/pages.xml
               */
              @Name("pageViewStack")
              @Scope(ScopeType.CONVERSATION)
              @AutoCreate
              public class PageViewStack implements Serializable
              {
                  int count = 0;
              
                  public PageViewStack()
                  {
                   views = new Stack<String>();
                  }
              
                  public void push()
                  {
                   String a = FacesContext.getCurrentInstance().getViewRoot().getViewId();
                   if (a == null)
                   {
                       return;
                   }
                   if (views.empty() || !views.peek().equals(a))
                   {
                       views.push(a);
                       count++;
                   }
                  }
              
                  /*
                   * This pops the top item and then returns the next item This is because the
                   * top item is always the active page, and we will be trying to move the the
                   * active pages parent
                   */
                  public String pop()
                  {
                   if (count > 1)
                   {
                       views.pop();
                       count--;
                   }
                   return views.peek();
                  }
              
                  Stack<String> views;
              
                  public int getCount()
                  {
                   return count;
                  }
              
                  public void setCount(int count)
                  {
                   this.count = count;
                  }
              }
              



              Then in pages.xml:



               <page action="#{pageViewStack.push}" login-required="true" view-id="/app/*" />
              <page view-id="/parent.xhtml">
                <action execute="#{pageViewStack.pop}"/>
               </page>
              



              Then if you redirect to '/parent.xhtml' it will redirect you to the previous page in the conversation, you can also use pageViewStack directly.





              • 4. Re: Return to "previous" view, or... current view - 1
                Acceleanu Dan Newbie

                I have a similar problem:
                In menu.xhtml, which is included in all pages, there is a link to 'Change Password' page. The expected behaviour is that the user can change his password from any page, that is go to the chpwd.xhtml and after a successful change return to whatever page it was that he came from.


                I thought that I could do it like this:


                - in menu.xhtml:




                <s:link
                     id="menuChangePasswordId"
                           view="/chpwd.xhtml"
                           value="Change Password" 
                           action="#{redirect.captureCurrentView}"
                           propagation="none"
                           rendered="#{identity.loggedIn}"
                />
                




                - in chpwd.page.xml:





                <action execute="#{userAction.editUser(credentials.username)}"/>
                 <navigation from-action="#{userAction.save}">
                    <rule if-outcome="success">
                        <action execute="#{redirect.returnToCapturedView}"/>
                    </rule>
                </navigation>
                





                This will fail because it expects @Begin(join=true) for userAction.editUser.
                (Exception - Caused by java.lang.IllegalStateException with message: begin method invoked from a long-running conversation, try using @Begin(join=true) on method: editUser)
                Is it really necessary for userAction.editUser to be just @Begin?
                What would be then an elegant solution to the problem?