Primefaces valueChangeListener or <p:ajax listener not firing for p:selectOneMenu [duplicate]

Solution 1:

If you want to use valueChangeListener, you need to submit the form every time a new option is chosen. Something like this:

<p:selectOneMenu value="#{mymb.employee}" onchange="submit()"
                 valueChangeListener="#{mymb.handleChange}" >
    <f:selectItems value="#{mymb.employeesList}" var="emp"
                   itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>

public void handleChange(ValueChangeEvent event){  
    System.out.println("New value: " + event.getNewValue());
}

Or else, if you want to use <p:ajax>, it should look like this:

<p:selectOneMenu value="#{mymb.employee}" >
    <p:ajax listener="#{mymb.handleChange}" />
    <f:selectItems value="#{mymb.employeesList}" var="emp"
                   itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>

private String employeeID;

public void handleChange(){  
    System.out.println("New value: " + employee);
}

One thing to note is that in your example code, I saw that the value attribute of your <p:selectOneMenu> is #{mymb.employeesList} which is the same as the value of <f:selectItems>. The value of your <p:selectOneMenu> should be similar to my examples above which point to a single employee, not a list of employees.

Solution 2:

The valueChangeListener is only necessary, if you are interested in both the old and the new value.

If you are only interested in the new value, the use of <p:ajax> or <f:ajax> is the better choice.

There are several possible reasons, why the ajax call won't work. First you should change the method signature of the handler method: drop the parameter. Then you can access your managed bean variable directly:

public void handleChange(){  
  System.out.println("here "+ getEmp().getEmployeeName());
}

At the time, the listener is called, the new value is already set. (Note that I implicitly assume that the el expression mymb.emp.employeeName is correctly backed by the corresponding getter/setter methods.)

Solution 3:

Another solution is to mix valueChangeListener, ajax and process:

<p:selectManyCheckbox id="employees" value="#{employees}" columns="1" layout="grid" valueChangeListener="#{mybean.fireSelection}"   >
    <f:selectItems var="employee" value="#{employeesSI}" />
    <p:ajax event="valueChange" immediate="true" process="@this"/>
</p:selectManyCheckbox>

Method in mybean is just :

public void fireSelection(ValueChangeEvent event) {
    log.debug("New: "+event.getNewValue()+", Old: "+event.getOldValue());
}

Like this, valueChangeEvent is very light !

PS: Works fine with PrimeFaces 5.0

Solution 4:

<p:ajax listener="#{my.handleChange}" update="id of component that need to be rerender after change" process="@this" />



import javax.faces.component.UIOutput;
import javax.faces.event.AjaxBehaviorEvent;

public void handleChange(AjaxBehaviorEvent vce){  
  String name= (String) ((UIOutput) vce.getSource()).getValue();
}

Solution 5:

All can be defined as in f:ajax attiributes.

i.e.

    <p:selectOneMenu id="employees" value="#{mymb.employeesList}" required="true">
         <f:selectItems value="#{mymb.employeesList}" var="emp" itemLabel="#{emp.employeeName}" />
         <f:ajax event="valueChange" listener="#{mymb.handleChange}" execute="@this" render="@all" />
    </p:selectOneMenu>

event: it can be normal DOM Events like click, or valueChange

execute: This is a space separated list of client ids of components that will participate in the "execute" portion of the Request Processing Lifecycle.

render: The clientIds of components that will participate in the "render" portion of the Request Processing Lifecycle. After action done, you can define which components should be refresh. Id, IdList or these keywords can be added: @this, @form, @all, @none.

You can reache the whole attribute list by following link: http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html