Jacob
Jacob

Reputation: 14731

Dependent p:selectOneMenu Population of values

I am using JSF 2.0 with Primefaces 3.4.2

I have two p:selectOneMenu, first one parent and second child, based on parent value, child component gets populated.

Parent p:selectOneMenu

<p:selectOneMenu id="empl" value="#{empMB.employee}">
<f:selectItems value="#{empMB.employeeList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeNumber}"/>     
                        <p:ajax update="department"  />                      
                    </p:selectOneMenu>

Child p:selectOneMenu

<p:selectOneMenu id="department" value="#{deptMB.department}">
<f:selectItems value="#{deptMB.loadDepartments(<??>)}" var="dept"
itemLabel="#{dept.departmentName}" itemValue="#{dept.departmentCode}"/>
                </p:selectOneMenu>

I have a method in department ManagedBean called loadDepartments with one argument

public void loadDepartments(String employeeNumber)

How can I pass value to loadDepartments in child component so that it will load all the departments based on the code selected in parent component?

If I am substituting #{deptMB.loadDepartments(empMB.employee.employeeCode)} I am getting

Error Parsing: #{deptMB.loadDepartments({empMB.employee.employeeCode})} 

Any help is highly appreciable?

Upvotes: 0

Views: 3045

Answers (1)

Andre
Andre

Reputation: 3904

I'd do this:

  1. Add a list variable to your bean (and the appropriate getter): this list will hold the values for the child combo box;
  2. Add a listener to the p:ajax call on the parent combo box: the listener populates the list of child values (you'll have access to the selected parent item inside its listener); and
  3. Update your xhtml to use the values from the list created on step 1 instead of the loadDepartments method you're trying to invoke.

This is normally how I do this sort of thing and it should work out for you.

EDIT

Code for the page:

<p:selectOneMenu id="empl" value="#{empMB.employee}" converter="#{employeeConverter}">
<f:selectItems value="#{empMB.employeeList}" var="emp" itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeNumber}"/>     
    <p:ajax update="department" listener="#{empMB.onEmployeeSelect}" process="@this"/>                      
</p:selectOneMenu>

<p:selectOneMenu id="department" value="#{deptMB.department}" converter="#{departmentConverter}">
    <f:selectItems value="#{empMB.departmentList}" var="dept" itemLabel="#{dept.departmentName}" itemValue="#{dept.departmentCode}"/>
</p:selectOneMenu>

Snippet for the bean:

public class EmpMB{
...
private List<Department> departmentList;
private Employee employee;

public List getDepartmentList(){
    return departmentList;
}

public void onEmployeeSelect(){
    departmentList = someService.getDepartmentsForEmployee(employee);
}
...
}

Converter sample (note that it's a spring component so that I can inject my service layer into it, but you don't HAVE to do it this way):

@Component("employeeConverter")
public class EmployeeConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
        //TODO: implement this
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        //TODO: implement this
    }

}

Upvotes: 4

Related Questions