14

Using PF 3.0-RC1 Snapshot (11/22/2011)

I have a in a composite component. I want to call the valueChangeListener when a selection is made, but it does not appear to be calling the listener.

Here is the code for the component:

<p:selectOneMenu style="width: 220px;" 
         value="#{customerProfileSessionBean.selectedAccount}"
         valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
    <f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>

The listener in the backing bean has a print statement that is not being called (at least I do not see it in the server log).

Is there something else that I need to do to get the valueChangeListener to be called when the value changes? Do I need to use ?

Also, in the listener, is there a ValueChangeEvent that is passed?

Thanks.

AlvaroCachoperro
  • 711
  • 6
  • 12
Burferd
  • 2,481
  • 7
  • 24
  • 24

2 Answers2

35

You seem to be expecting that the valueChangeListener method in the server side is called immediately when a change event occurs on the client side. This is not correct. It will only be invoked when the form is submitted to the server and the new value does not equals() the old value.

There are at least two ways to achieve your functional requirement:

  1. Add onchange="submit()" so that JavaScript will submit the form whenever you change the value:

    <p:selectOneMenu style="width: 220px;" 
       value="#{customerProfileSessionBean.selectedAccount}"
       valueChangeListener="#{customerProfileSessionBean.accountValueChange}"
       onchange="submit()">
        <f:selectItems value="#{sessionBean1.custAccountList}"/>
    </p:selectOneMenu>
    

    This is however very JSF-1.x-ish and poor for user experience. It will also submit (and convert/validate!) all other input fields which may not be what you want.

  2. Make use of an ajax listener instead, for sure if you are not interested in the actual value change (i.e. the old value is not interesting for you), but you're actually interested in the change event itself. You can do this using <f:ajax> or in PrimeFaces components using <p:ajax>:

    <p:selectOneMenu style="width: 220px;" 
       value="#{customerProfileSessionBean.selectedAccount}">
        <p:ajax listener="#{customerProfileSessionBean.accountValueChange}" />
        <f:selectItems value="#{sessionBean1.custAccountList}"/>
    </p:selectOneMenu>
    

    And replace the ValueChangeEvent argument by the AjaxBehaviorEvent argument.

AlvaroCachoperro
  • 711
  • 6
  • 12
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks. I was exxpecting the PrimeFaces component to do the submit() as part of the component's ajax behavior. – Burferd Dec 07 '11 at 20:26
  • 6
    Your selcond solution worked very well for be, but only if i changed the ` – devsnd May 04 '12 at 12:36
  • 1
    BalusC is spot on.Even more fun, although I am not sure if it is legit., is just to insert inside the menu and leave the valueChangeListener attribute of the menu intact. For some reason the ajax will fire the valueChangeEvent when the item changes. I have tested this exhaustively to make an immediate change to a locale and it works a dream. – Tim Maher-De Troyer Jul 04 '13 at 17:04
  • 2
    @Tim: The value change listener is fired when the submitted value differs from the initial value. All what ajax does is submitting the form. That's not so weird as you seem to imply. However, if you're not intersted in the change itself, but only in the newly submitted value, then a value change listener is the wrong tool for the job. See also http://stackoverflow.com/questions/11879138/when-to-use-valuechangelistener-or-fajax-listener/ – BalusC Jul 04 '13 at 17:58
3

Add f:ajax statement for p:selectOneMenu , it will create ajax call and your value will be submitted EX:

      <p:selectOneMenu style="width: 220px;" value="#  
      {customerProfileSessionBean.selectedAccount}"
             valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
      <f:selectItems value="#{sessionBean1.custAccountList}"/>
       <f:ajax render="@form"/>
       </p:selectOneMenu>

Or you can provide panel id or datatable id ,if you dont want torender the whole form, like:

    <f:ajax render=":formid:panelGroupId"/>
Bosco
  • 3,835
  • 6
  • 25
  • 33