Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<p:selectOneMenu listener method returns null when a value is selected

I am using JSF 2.0 with Primefaces 3.4.2

I have the following in JSF page

<p:selectOneMenu value="#{mb.employee}">
    <f:selectItems value="#{mb.employeeList}" var="emp"
    itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeCode}"/>
    <p:ajax listener="#{mb.changeMethod}" />
</p:selectOneMenu>

Problem is when I select a value in selectOneMenu, I am getting null in changeMethod of ManagedBean, for this System.out.println("val "+employee.getEmployeeName());

What could be the reason for this? How can I resolve this problem? Any hep is highly appreciable.

ManagedBean Code

@Named("mb")
@ViewAccessScoped
public class MyBean implements Serializable {

private Employee employee;
private List<Employee> employeeList;

@Inject
EmployeeService employeeService;

@PostConstruct
public void loadEmployees() {
employeeList = employeeService.getEmployees();
}


public void changeMethod() {
System.out.println("val  "+employee.getEmployeeName());
}


/* getters and setters for employee and employeeList */
.... methods
/* */
like image 279
Jacob Avatar asked Dec 20 '22 09:12

Jacob


2 Answers

You are not specifying on the <p:ajax> component which form elements to process, so the ajax request may be submitting multiple values that could be conflicting with other field validation. Remmeber that if a value is submitted and it fails validation, then none of the request values get set to the model. When you reach the Application(Event) phase, the model values will not reflect any submitted request values.

Try this:

<p:selectOneMenu value="#{mb.employee}">
    <f:selectItems value="#{mb.employeeList}" var="emp"
    itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeCode}"/>
    <p:ajax process="@this" partialSubmit="true" listener="#{mb.changeMethod}" />
</p:selectOneMenu>

Above you will be submitting just the current component request value to be applied to the model.

EDIT:

Actually it probably isn't a validation issue so much as there are no request values being submitted on the ajax event.

According to the Primefaces Manual:

process null String Component(s) to process in partial request.

update null String Component(s) to update with ajax.

The second column is Default Value. In the standard <f:ajax> the execute attribute defaults to @this however this is not the case for <p:ajax>. If you want to submit the current component then you must specify this in the process attribute.

like image 170
maple_shaft Avatar answered Jan 15 '23 13:01

maple_shaft


You need to add converter to p:selectOneMenu to let it know that you are dealing with employee object. Create the converter class and use it with converter attribute. Here is the sample converter.

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@FacesConverter("employeeConverter")
@Configurable
public class EmployeeConverter implements Converter {

    @Autowired
    EmployeeService employeeService;

    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        if (value == null || value.length() == 0) {
            return null;
        }
        Long id = Long.parseLong(value);
        return employeeService.findUser(id);
    }

    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        return value instanceof Employee ? ((Employee) value).getId().toString() : "";
    }
}
like image 28
Thiha Maung Avatar answered Jan 15 '23 14:01

Thiha Maung