0

I use Pretty Faces and JSF 2.

I have a selectOneMenu to choose a value. I want then to pass the selected value to a second form with a command button to pass then to an another page. I don't want to see the parameter in the URL.

I don't want the url as this : addpartipant.xhtml, or addparticipant.xhtml?study_name=TEST or /Addparticpant/New/TEST.

I want the URL like this only /Addparticipant/New but if I do this , I don't get to retrieve the good parameter value, I'm only retrieving the value set by default in the bean for the parameter, not the page refreshed value.

More disturbing, I have a button who appears when i change the default value in the page.And it works but it looks like the bean value of parameter is not impact and still stay at default.

How should I to that? Thank for help. I tried so listener in ajax call to set the value param in bean but it's actually not working?

/* Form which throws an ajax event when you change the value of the selectOneMenu to add the value as a parameter to a second form */

<h:form id="studySelection_form">
  <h:outputText value="Sélection de l'étude :"/>
  <h:selectOneMenu  id="study" 
                    value="#{home.study_name}" 
                    required="true"
                    requiredMesage="Selectionnez au moins une étude.">
    <f:selectItems value="#{home.studyNameItems}" 
                   var="c" 
                   itemLabel="#{c.studyNameLabel}" 
                   itemValue="#{c.studyNameValue}" />

    <f:ajax execute="study" 
            render=":add_form" 
            event="change" 
            listener="#{home.updateStudyname}"/>
   </h:selectOneMenu>
 </h:form>

/* Second form where the parameter to pass is injected from an ajax call from a move event from the form below */

 <h:commandButton value="Ajout" 
                  type="button" 
                  action="pretty:participant" 
                  rendered="#{home.study_name ne '-----'}" >
   <f:param name="theNameofTheStudy" 
            value="#{home.study_name}"  />
 </h:commandButton>

PrettyFaces Config File :

<url-mapping id="participant">
  <pattern value="/Participant/New/" />
  <view-id value="/addParticipant.xhtml" />
</url-mapping>

Page Result addParticipant.xhtml:

<h:outputFormat value="Print : {0}, {1} ">
  <f:param value="#{home.study_name}" />
  <f:param value=" #{theNameofTheStudy}" />
</h:outputFormat>
Valentin Jacquemin
  • 2,119
  • 1
  • 18
  • 33
ZheFrench
  • 1,065
  • 2
  • 19
  • 41
  • 1
    You basically have two choices. One is not to perform a `redirect`, so the url in the browser won't change. The second one is to use flash scope or similar, to, in some way, preserve your param value from one view to another. – Xtreme Biker Oct 22 '13 at 15:39
  • Pretty Faces always used redirection ? No ? In fact, I have to let down Pretty faces and use something like thaht with action="addParticipant" – ZheFrench Oct 22 '13 at 15:57
  • And i don't understand how to retrieve parameter, do i have to use #{home.study_name}" or #{theNameofTheStudy}" in the destination page. ('home' is the bean from the sender page) – ZheFrench Oct 22 '13 at 16:04

2 Answers2

0

Prettyfaces always uses POST-REDIRECT-GET pattern to perform the navigation. So your chance is to invoke a managed bean method in your h:commandButton action method instead of returning the navigation result itself and put your parameter in flash scope:

<h:commandButton value="Ajout" 
    action="#{home.actionGoToAddStudent}" 
    rendered="#{home.study_name ne '-----'}" />

And in your managed bean:

public String actionGoToAddStudent(){
    FacesContext.getCurrentInstance().getExternalContext().getFlash().put("param1", study_name);
    return "pretty:participant"; //or just "/addParticipant.xhtml" and Prettyfaces will translate to pretty url
}

After that, you can retrieve param1 from your destination managed bean. That's for using hidden parameters.

Whenever you want to use standard visible GET parameters, you'll find this post helpful. Using GET parameters involves sending them with the GET request, so your destination page has to catch them with an <f:viewParam> and can keep them into a destination managed bean property. Here you can refer to my previously answered question:

Source page:

<!--Performs a GET request with study param-->
<h:button value="Basic GET request" outcome="pretty:participant">
    <f:param name="study" value="#{home.study}" />
</h:button>

Destination page:

<f:metadata>
    <!--Takes the study param and sets it into the destination bean's property-->
    <f:viewParam name="study" value="#{destinationBean.study}" />
</f:metadata>

<h:outputFormat value="Print : {0} ">
   <f:param value="#{destinationBean.study}" />      
</h:outputFormat>
Community
  • 1
  • 1
Xtreme Biker
  • 28,480
  • 12
  • 120
  • 195
  • I propose an another solution without PrettyFaces and ask others questions above relative to the subjects. Thanks. – ZheFrench Oct 23 '13 at 09:20
  • getFlash() throws an error - java.lang.NoSuchMethodError: javax.servlet.http.Cookie.isHttpOnly()... I come from a Login page (Spring Security) to my home.xhtml (session scope,maybe i will change to view scope, i'm actually reading stuffs about scope and how use them) and then i want to go to addParticipant.xhtml to add something in my database (request scope).That's the global idea. – ZheFrench Oct 23 '13 at 10:25
  • That depends on your servlet api version, which server are you using? – Xtreme Biker Oct 23 '13 at 10:29
  • Is this Ok with this version ? Mojara is 2.2.0 . I didn't resolve the error yet to use flash scope. – ZheFrench Oct 24 '13 at 07:28
  • Flash scope is still a bit buggy in Mojarra, it seems. I recomend you to update to the latest version, but even there is not already solved for some browsers. To use it with Tomcat 6 I encourage you to go with Mojarra 2.1.x branch, try 2.1.26. 2.2.x branch is more tied to Servlet 3.0 specification (Tomcat 7). – Xtreme Biker Oct 24 '13 at 07:34
  • I haven't set a production server yet. I will try to install Tomcat 7 with TomEE as a consequence I can keep Mojarra 2.2.x.. I hope it will not impact too much on my configuration. – ZheFrench Oct 24 '13 at 07:50
  • It's works! using Tomcat 7. Thanks for you help. So i understand flash scope ok but i'm still in trouble with the spirit of the classic way. I mean if I choose to use /Participant/New/#{home.study_name} (note that using #{param.study_name} is buggy...) in prettyConfig.xml you tell me that i will retrieve param with f:viewparam and set the receiver backing bean using value="#{participant.study_name} but when i tried to print #{param.studynameItem} & #{participant.study_name} both are null...i could retrieve #{home.study_name} from the backing bean sender but it makes no sense... – ZheFrench Oct 24 '13 at 14:55
  • Hummm OK I UNDERSTAND NOW . I made work the 'classic way' with passing parameter to Url as this /Participant/New/#{studynameItem:home.study_name} . THis way, it's working fine...and if you delete the , #{patient.study_name} will become null because instanciation/linkage is no more done inside viewparam with the backing value. Okkkkkkk , Hard day :) – ZheFrench Oct 24 '13 at 15:06
  • 1
    Using `/Participant/New/#{participant.study_name}` (note I use destination bean here) and just `/Participant/New/` combined with `f:viewParam` in destination page **is redundant**. It means, they **do the same thing**. Look at [my old thread](http://stackoverflow.com/questions/14484348/prettyfaces-error-with-required-attribute), discussing with PrettyFaces' team lead. However, I highly recommend you to use the second approach, meaning not to include EL expression directly in url mapping. Anyway, glad to see it helped to solve it! – Xtreme Biker Oct 24 '13 at 15:09
0

As you said before, another solution could be to simply use forward with the JSF navigation. The parameters are kept hidden stuck to the first navigation url page (for example we could said /Home) . But ok you won't have the /Addparticpant/New/TEST style.

What is the avantage of POST-REDIRECT-GET offered by PrettyFaces ? And f:param is in fact pointless when you use PrettyFaces because of the POST...unless you use GET (which means you don't use PrettyFaces) & you put parameters in URL. I will read your link because i get some problems in fact to retrieve my parameters according to the scopes, the Post/Get Action & the place( In JSF page/ backing bean).

Alternative Solution :  

    <navigation-rule>
       <from-view-id>/home.xhtml</from-view-id> 
       <navigation-case>
          <from-outcome>participant</from-outcome>
          <to-view-id>/addParticipant.xhtml</to-view-id>
       </navigation-case>
    </navigation-rule>


    /*I use viewparam but if I don't use it it's working too, I clearly don't understand what viewparam is used for  */

    <f:metadata>
          <f:viewParam name="study_name" value="#{home.study_name}" required="true"/>
     </f:metadata>

   /* What is the best way to retrieve information? Then how i load param in a backing bean who this destination page ? */ 
   <h:outputFormat value="Hello,{0},{1},">
                <f:param value="#{home.study_name}" />
                <f:param value="#{param.studynameItem}" />
    </h:outputFormat>
ZheFrench
  • 1,065
  • 2
  • 19
  • 41
  • 1
    You're actually mixing param concepts. Supposing you have a managed bean tied to your home page and other one to your add student page, `/addParticipant.xhtml` doesn't have to access `home` bean, never. That's what view params are used for. Also keep in mind PrettyFaces is used in practice to perform GET requests, means, to GET a content page. I'll update my answer to give you some tips. Also, POST-REDIRECT-GET has its advantages, as it's a clean and clear pattern, and its cons, as it takes more time for the browswer to update the content, as two request cycles have to be performed. – Xtreme Biker Oct 23 '13 at 09:36
  • However, I'm not yet sure about what you want to achieve. Your alternative solution yet goes with PrettyFaces... – Xtreme Biker Oct 23 '13 at 09:46
  • I'm totally ok that addParticipant doesn't have to access home bean.That was just a solution I found and was working...but clearly not a good way... I want to have a clean URL, to hide my parameters, retrieve them in Addparticipant.xhtml and inject them in backing bean AddBeanParticpant relative to Addparticipant.xhtml. I'm looking for a clean example where your retrieve parameters.You could show me one where parameters are shown and one where they are hidden. For the hidden case, is there a particular scope to use? I will read about that.Thanks. – ZheFrench Oct 23 '13 at 09:59
  • Just go with flash scope (the first example I showed you in my answer). The home bean puts the parameter you want to pass in the action method. After that, when redirect is done, you can use a [`prerenderView`](http://stackoverflow.com/a/14647248/1199132) event, which will initialize the destination bean and in that bean you can access the flash map, where your parameter must be stored in. – Xtreme Biker Oct 23 '13 at 10:27