9 Replies Latest reply on Mar 24, 2009 12:32 PM by josief

    Problem ending conversation in RichFaces MenuItem

    susnet.susanne.susnet.se
      When I click on a menu item I want old conversations to end and a new pageflow to start.

      The following code for this works. What happens is that a new conversation is started and the user is redirected to the chooseSubject page defined by the transition in the jpdl.

      <rich:menuItem submitMode="none">                    
        <s:link id="personHandout" propagation="none" action="#{handout.personHandout}" view="/pages/handout/chooseSubject.xhtml" value="to person"/>                         
      </rich:menuItem>

      Action method in handout component:
      @Begin(pageflow = "handout")
      public void personHandout() {       
        log.debug("Person handout");       
      }

      JPDL:
      <start-state name="start">         
          <transition name="next" to="chooseSubject"/>       
      </start-state>


      But now, the problem is that I have to click on the link in the menuItem for this to work. I want to be able to click on the whole menuItem area.

      So I tried the following:

      <rich:menuItem action="#{handout.personHandout}" value="to person" submitMode="server" >
        <s:conversationPropagation type="none" />                                        
      </rich:menuItem>

      the problem is that it does not work when another conversation is present. Then my action method never gets called and I end up in no-conversation-page of the previous conversation with an error message saying "The conversation ended.". But if no other conversation is present it works fine.

      Any ideas of how to make this work? Since I can't have multiple start pages in a pageflow I need to start the pageflow from an action method in a bean and for usability reasons I need to be able to click on the whole menuItem area and not just the link.
        • 1. Re: Problem ending conversation in RichFaces MenuItem
          susnet.susanne.susnet.se

          I discovered that none of the above code works. Both get me the conversation ended error message.


          I use


          conversation-required=true



          for these other conversations. My question is how I can end them and in on action method or one s:link also start a new conversation and/or pageflow.


          Is that possible or do the user have to click two buttons to first end the conversation and then start a new one?


          I have a menu where I always want to end the previous conversation and start a new one when I click on a menu item.


          Any ideas?

          • 2. Re: Problem ending conversation in RichFaces MenuItem
            tamerg

            Hi try this,


            in your menu item



            <rich:menuItem submitMode="ajax" action="#{Util.globalRedirect('/pages/handout/chooseSubject.xhtml')}
            value="to person']}"/>
            



            and add an util function somewhere like this


            @End(beforeRedirect=true)
            public String  globalRedirect(String pageName){
                   return pageName ;        
            }
            



            • 3. Re: Problem ending conversation in RichFaces MenuItem
              susnet.susanne.susnet.se

              Thanks for your answer, but I guess your solution only ends the conversation and does not start a new conversation.


              I want to be able to click on menuItem and both end and begin a new conversation. For example if this would be possible:



              <rich:menuItem submitMode="ajax" action="#{myBean.someMethod)}" value="some text']}">
              <s:conversationPropagation type="end" />
              <s:conversationPropagation type="begin" />
              </rich:menutItem>




              Where the conversation is immediately ended and a new one begins. And the ending of a conversation does not give you the message Conversation Ended and redirection to the No-conversation-page.


              Also I wonder how to both end and start conversations in the beans.


              For example would this be possible:



              @End(beforeRedirect=true)
              @Begin
              public void someMethod() {
              // some code
              }




              or like this:



              @End(beforeRedirect=true)
              public void someMethod() {
               someOtherMethod();
              }
              
              @Begin
              public void someOtherMethod() {
              // some code
              }




              Thanks in advance for your answer!

              • 4. Re: Problem ending conversation in RichFaces MenuItem
                tamerg

                Also add this to your chooseSubject.page.xhtml



                <begin-conversation join="true"/>


                • 5. Re: Problem ending conversation in RichFaces MenuItem
                  vincent.crepin

                  You can end a conversation and start a new one like this :


                   <rich:menuItem submitMode="ajax" ajaxSingle="true"
                                                                  id="monthListManageCarsMenuItem"
                                                                  value="#{messages['KilometerEntryMonthList.manageCars.label']}"
                                                                  action="#{com_servier_hr_session_uievents_KilometerEntryMonthSearch.gotoCarManagementList()}">
                                                                  <f:facet name="icon">
                                                                          <h:graphicImage value="/img/actions/car.gif" />
                                                                  </f:facet>
                                                          </rich:menuItem>
                  



                  The action is on the backing bean of the current page.


                  Here is the code of the action :


                  @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                          @End
                          public String gotoCarManagementList(){          
                                  return "carList";
                          }




                  carList is the logical name of the other page you want to go and needs a new conversation. Here is its description in pages.xml :


                  <page view-id="/kilometerEntry/kilometerEntryMonthList.xhtml"
                                  login-required="true"  conversation-required="true">
                                          <description>The month list page of the application</description>
                                  
                                  <navigation>
                                          <rule if-outcome="carList">
                                                  <redirect
                                                          view-id="/kilometerEntry/#{com_servier_hr_session_uievents_carListAction.enterList()}.xhtml">
                                                  </redirect>
                                          </rule>
                                  </navigation>
                          </page>
                  
                          <page view-id="/kilometerEntry/carList.xhtml"
                                  login-required="true"  conversation-required="true">
                                          <description>The car list page of the application</description>
                                  
                                  <navigation>
                                          <rule if-outcome="kilometerEntryMonthList">
                                                  <redirect
                                                          view-id="/kilometerEntry/#{com_servier_hr_session_uievents_KilometerEntryMonthSearch.enterList()}.xhtml">
                                                          <param name="conversationPropagation" value="end" />
                                                  </redirect>
                                          </rule>
                                  </navigation>
                          </page>



                  You see that the navigation rule of the page you quit calls an entry method on the bean of the new page you want to go to. Here is the code :


                  @Begin
                          @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                          public String enterList() {
                                  this.com_servier_hr_session_uievents_carList = null;
                                  queryObjects();
                                  return "carList";
                          }




                  Voila, it ends a conversation and starts a new one.


                  Cheers.

                  • 6. Re: Problem ending conversation in RichFaces MenuItem
                    susnet.susanne.susnet.se

                    Thanks for all your answers! But I really must say that the solutions are very complicated and require a lot of code that is only there to solve this problem and therefore looks ugly. I don't understand why there is no simpler way to do this? I would like it to be as in my examples. Maybe I should add this in a feature request?

                    • 7. Re: Problem ending conversation in RichFaces MenuItem

                      Well, with some help from Guillaume Jeudy, I almost found the way to discard the current conversation and a new one (but I am no using JPDL). In fact, it is not a good idea to end the previous conversation, remember that users love tabbed browsing, and they will want to start a different conversation on each tab (they will get really frustrated if starting a new tab ends the conversation in the previous one), if you do not want that, then ScopeType.CONVERSATION is not the answer, ScopeType.SESSION is.


                      But I am stuck now because I can not find a nice way to stop parameter propagation. Any recommendations?

                      • 8. Re: Problem ending conversation in RichFaces MenuItem
                        vladimir.kovalyuk

                        I'd like to raise up this topic because I'm not happy with Richfaces menus and how they work with Seam.


                        Richfaces menus don't care about the cases when there is an active long running conversation. And it is not so bad, they actually should not know about Seam. It is Seam responsibility to leave conversation on action. But Seam does not offer annotation or pages.xml tag or attribute to accomplish that. As the result when the user is in long running conversation and presses menu item it stays in the same conversation. That's the big problem.


                        I figured out a way around it. I introduced redirector class which provides several redirect methods as in the following excerpt:



                             void goto(String viewId, Map<String, Object> params) {
                                  viewId = getPrefix() + viewId;
                                  Redirect.instance().setViewId(viewId);
                                  Redirect.instance().setConversationPropagationEnabled(false);
                                  if (params != null)
                                       for (Map.Entry<String, Object> entry : params.entrySet())
                                            Redirect.instance().setParameter(entry.getKey(), entry.getValue());
                                  Redirect.instance().execute();
                             }
                        



                        From the other hand the problem can be easily fixed by introducing


                        <redirect propagation="none">



                        in pages.xml


                        I don't understand why pages.xml does not provide such a capability.

                        • 9. Re: Problem ending conversation in RichFaces MenuItem
                          josief

                          My solution on this problem:


                          MenuBean.class:


                          @Name("menuBean")
                          @Scope(ScopeType.SESSION)
                          public class MenuBean {
                              public String clickAndKillLastConversation(final String viewId) {
                                  log.debug("clickAndKillLastConversation : clicked on " + viewId);
                                  Manager.instance().endRootConversation(true);
                                  return viewId;
                          }





                          menu.xhtml:


                          <rich:menuItem value="#{msg['inrianeurotk.menu.subject']}"
                                                   action="#{menuBean.clickAndKillLastConversation('/manageData/manageSubjects.xhtml')}">
                                                   <f:facet name="icon">
                                                        <h:graphicImage value="/img/subject.16x16.png" />
                                                   </f:facet>
                                              </rich:menuItem>



                          manageSubjects.page.xml:


                          <?xml version="1.0" encoding="UTF-8"?>
                          <page>
                               <begin-conversation flush-mode="manual" join="true"/>
                          </page>