zaterdag 10 november 2012

Cascading Select One Choice using Bean data in ADF

Use case:

Somebody on the Oracle forum had trouble making 2 cascading SOC (Select One Choice) using data from his bean.
First of all, you can find the application here. It doesn't use any database connection so everybody can run it. I made 2 objects named Company and Employee in my Model project so I will be using those in this blog post. 
You could just check out the application or follow the basic steps in the solution underneath.

My Solution:

1) Make a new Fusion Web Application with a Model and ViewController project. In the Model, make 2 java classes (Company and Employee) and copy the code from my application into those classes.
2) Make a new Page in your ViewController, name it whatever you want , and open it.

3) In that page I added a Panel Header so I could make a new managed bean for my page.

In the 'Property Window' go to Advanced, select 'Binding' and click 'Edit' (using the arrow on the right). 

And add a new Managed Bean. When this is created, just click cancel in the 'Edit Property: Binding' popup.

4) Open the bean you just created. 
I added these 2 attributes in the bean:
    private List<Company> companyList;
    private List<Employee> empList;
They will hold my data.
I also changed my constructor to this :
    public TestBean() {
        companyList = new ArrayList<Company>();
        empList = new ArrayList<Employee>();
        companyList.add(new Company(1,"Oracle"));
        companyList.add(new Company(2,"Cookie Company"));
        //They work for Oracle (id: 1)
        empList.add(new Employee(1,"Yannick","O."));
        empList.add(new Employee(1,"Frank","N."));
        //They work for Cookie Company (id: 2)
        empList.add(new Employee(2,"Cookie","Monster"));
        empList.add(new Employee(2,"Hannes","D.M."));
        empList.add(new Employee(2,"Donaat","M."));      
So my companyList and empList would contain data.

5) Now lets add 2 other methods to our bean.
    public List<SelectItem> getCompanySelectItems()
          List<SelectItem> companiesSelectItems = new      ArrayList<SelectItem>();
          for (Company comp: companyList)
            //SelectItem constructor (value, label)
            SelectItem item = new SelectItem(comp, comp.getName());
          return companiesSelectItems;

This is the first one, this method return a list of SelectItem which will populate the first SOC (the one with the companies). The value of SelectItem is my company object, the label is just the name. The label is what the user is going to see on the page, the value is what we need to populate the second SOC (the one for the employees).

Before we add the second method, I added this one to the attributes of my bean :
private Company selectCompany;
This one will hold the company that has been selected in the first SOC.
Now lets add the second method.
    public List<SelectItem> getEmployeSelectItems()
          List<SelectItem> employeeSelectItems = new ArrayList<SelectItem>();
          if(selectCompany != null)
              for (Employee emp: empList)
                if(emp.getCompanyID() == selectCompany.getId())
                   //SelectItem constructor (value, label)
                   SelectItem item = new SelectItem(emp, emp.getFirstname() +" "+ emp.getLastname());
          return employeeSelectItems;
Like you can see, this list that is generated here is depended on the company that has been selected. Because we only want to select the employees who work for the company that we have selected.

6) Now lets get back to the our page. In the component palette, search for 'Choice' and drag it onto your page.
A popup window will show up. Do the same as in the screenshot below (this selects the data for the SOC).

And press next. Give your SOC a name and add a valueChangedListener (like below).

And finish up the popups so you will go back to your page. Select the SOC you just added and go to the 'Property Inspector' and set 'autoSubmit' to true. Now go back to your bean.

7) There will be a new method add the end of the bean. Change it so it looks like this:
    public void companyChangedListener(ValueChangeEvent valueChangeEvent) {
        selectCompany = (Company)valueChangeEvent.getNewValue();

8) Get back to your page and repeat step 6 but select the list for the employees of course. You also don't have to add a valueChangeListener and instead of setting autoSubmit to true, set the PartialTrigger to 'soc1' or whatever the ID is of your first SOC is. 

9) Now run your page an behold the power of cascading SOCs!

2 opmerkingen:

  1. can you please provide the images for the Assingment.

    1. I lost some images somehow and I don't have a backup. Sorry.
      But I will try to update this asap.