7 Replies Latest reply on Mar 27, 2007 7:56 PM by henrik.lindberg

    How to link to page using level of indirection

    henrik.lindberg

      Hi, I currently have this:

      <h:outputLink value="object-view.seam">
       <f:param name="oid" value="#{x.id}"/>
       <h:outputText value="#{x.name}" />
       </h:outputLink>
      

      to go to a detailed view of the object when clicked on the link.
      I want to be able to call a method to determine which view to go to depending on the Class of x.

      Essentially what I would want to do is write:
      <h:outputLink value="#{myViewSelector.selectViewFor(x)}">
       <f:param name="oid" value="#{x.id}"/>
       <h:outputText value="#{x.name}" />
       </h:outputLink>
      


      I have written a ViewSelector class with a method that takes an instance of x and determines which view I want, I then return "object-view.seam" or something similar.

      This does not work, so I wonder how I am supposed to do this.
      Any suggestions that helps a newbie like me are much appreciated.


        • 1. Re: How to link to page using level of indirection
          awheeler

          You could use <s:link> with action parameter. The action event should return a view-id (JSF or otherwise). Using the SeamFaceletViewHandler you should be able to pass parameters to the action event e.g #{myBean.objectSelected(x)}

          • 2. Re: How to link to page using level of indirection
            henrik.lindberg

            Thanks, after some tweaking (and forgetting to have a "/" first in the view-id :-( ) I got it working. This is what I ended up with:

            <s:link
             action="#{viewSelector.viewForObject(x)}"
             value="#{x.name}">
             <f:param name="oid" value="#{x.id}"/>
            </s:link>
            


            I think this could be clarified in the documentation under the s:link, s:button section - i.e. add:
            "If you want the action to result in a redirect to a view, please remember to include a leading '/', otherwise the returned string is interpreted as an 'outcome' (that can be redirected using declarations in pages.xml)."

            It would also be very helpful if the s:link section included that it is possible to use f:param to pass on parameters.

            Regards

            • 3. Re: How to link to page using level of indirection
              henrik.lindberg

              Well - actually - I was not paying attention - it did not work - as I did not get the oid parameter in the URL.

              How should that be done when using s:link ?

              • 4. Re: How to link to page using level of indirection
                henrik.lindberg

                The f:param was passed as a parameter in the URL that leads to the viewSelector - so the question is how to get a page parameter into the result from the action ???

                • 5. Re: How to link to page using level of indirection
                  henrik.lindberg

                  I really need help - I am stuck on this.

                  Basically I want to do:

                  <a href="#{viewSelector.viewForObject(x)}?oid=#{x.oid}">some text</a>
                  

                  But I have failed to figure out how to create such an URL.
                  If I use s:link I can call the method viewForObject and pass a paramter and get the view back, but then the parameter is lost (it is applied to the invocation of the action).

                  I then thought about using multiplen h:outputLink with static declaration of the various viewids and using
                  rendered="#{viewSelector.viewForObject(x) == 'view-x'}"
                  

                  but that is not valid (or? can this be made to work?)

                  I then looked at doing this with a page navigation rule instead, but my head starts to spin - how do this with page rules?
                  Should I have a fictious page-id that I navigate to with
                  redirects depending on the outcome of my method? Or add a page that never gets rendered, only redirected from? But how do I get the value of x.id in there?

                  Any help much appreciated...
                  Regards
                  "confused newbie"

                  • 6. Re: How to link to page using level of indirection
                    awheeler

                    Your selection action passes the object x. You may be able to return a string of the view such as "/myobjectview.seam?id=" + x.id. I haven't tried this.

                    Better still you could use the navigation rules in pages.xml as per the seam documentation (section 5.1.1.2):

                    <page view-id="/viewSelector.xhtml">
                    
                     <navigation from-action="#{viewSelector.viewForUpdate}">
                     <rule if="objectViewOne">
                     <end-conversation/>
                     <redirect view-id="/objectViewOne.xhtml">
                     <param name="id" value="#{viewSelector.x}"/>
                     </redirect>
                     </rule>
                     </navigation>
                    
                    </page>
                    


                    • 7. Re: How to link to page using level of indirection
                      henrik.lindberg

                      Thanks awheeler - I tried the first but did not succeed.

                      And thanks for the page navigation-rule example. I got confused thinking that I needed to have from-action include parameter - but your example makes it clear, I just have to keep x from the call to virewForUpdate in the ViewSelector instance so I can pick it up again as a parameter. Understand how to make that work.

                      What I don't like about this solution is that it ads yet another place to configure the mapping.

                      What I ended up doing was this:

                      <h:outputLink value="#{x.type}-view.seam" >
                       <f:param name="oid" value="#{x.id}" />
                       #{x.name}
                      </h:outputLink>
                      

                      Which naturally is far less elegant as it ties the view to the type (which I already had).
                      Will explore the page navigation rule approach sometimes later.

                      I would have loved to have this possibility directly available in s:link (i.e. ability to call method with parameter to set the value).

                      Regards