Friday, June 1, 2012

Bean DataControl - Create new table rows based on existing row content

The Create a Duplicate row enables the user to create an object by duplicating an existing object. The duplication aids the user by prefilling some values. The user has full control and can change any of the values during the creation process. So in this article, I'm will show how can we create new table rows based on existing rows using Bean Data Control.

This can be achieved in BC4J using "Create With Parameters" operation, there is an example written by Frank Nimphius in ADF code corner "How-to declaratively create new table rows based on existing row content".

[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2)]

At runtime page looks like below, you can now select a table row and press the "Copy Row" button. New row will be created by prefilling the selected row values.


Implementations Steps:

There are lot of ways to create a new in an iterator and populate the values from existing row, below I'm showing one of the way to achieve that.

Create Fusion Web Application, create the DeptBean.java and GenericBean.java classes in model project. Open the DeptBean.java and paste the below code.
public class DeptBean {
    private String deptNo;
    private String deptName;
    private String deptLocation;

    public DeptBean() {
        super();
    }

    public DeptBean(String deptNo, String deptName, String deptLocation) {
        this.deptNo = deptNo;
        this.deptName = deptName;
        this.deptLocation = deptLocation;
    }

    public void setDeptNo(String deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptNo() {
        return deptNo;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptLocation(String deptLocation) {
        this.deptLocation = deptLocation;
    }

    public String getDeptLocation() {
        return deptLocation;
    }
}
Open the GenericBean.java and paste the below code. Here static values are populated to show in result list.
/**
 * Populating Dept static values to DeptBean
 * @return DeptBean list
 */
    public List populateBean() {
        System.out.println("populateBean");
        List deptList = new ArrayList();
        {
            DeptBean dept = new DeptBean("10", "Administrator", "1700");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("20", "Marketing", "1800");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("30", "Purchasing", "1700");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("40", "Human Resource", "2400");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("50", "Shippings", "1500");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("60", "IT", "1400");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("70", "Public Relations", "2700");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("80", "Sales", "2500");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("90", "Executive", "1700");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("100", "Finance", "1700");
            deptList.add(dept);
        }
        {
            DeptBean dept = new DeptBean("110", "Accounting", "1700");
            deptList.add(dept);
        }
        return deptList;
    }

Now right click on GenericBean.java file and generate data control. Open the DataControl.dcx file in application navigator and select the GenericBean. Go to the GenericBean property inspector and set SupportsTransactions as true.

In ViewController project, create index.jspx page and "IndexBean.java". Add the  IndexBean.java file in adfc-config.xml file with scope as viewScope.

Open the IndexBean.java file and paste the below code.
private String deptNo;
private String deptName;
private String deptLocation;

public IndexBean() {
}

public void setDeptNo(String deptNo) {
 this.deptNo = deptNo;
}

public String getDeptNo() {
 return deptNo;
}

public void setDeptName(String deptName) {
 this.deptName = deptName;
}

public String getDeptName() {
 return deptName;
}

public void setDeptLocation(String deptLocation) {
 this.deptLocation = deptLocation;
}

public String getDeptLocation() {
 return deptLocation;
}

public void populateCopyRow(ActionEvent actionEvent) {
 //Executing the Create Method
 BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
 OperationBinding operBind = bindings.getOperationBinding("Create");
 operBind.execute();

 DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
 DCIteratorBinding customIter = dcBindings.findIteratorBinding("populateBeanIterator");
 RowSetIterator customRSIter = customIter.getRowSetIterator();
 //Populating the data to newly created row
 Row currentRow = customRSIter.getCurrentRow();
 System.out.println(this.getDeptName());
 currentRow.setAttribute("deptNo", this.getDeptNo());
 currentRow.setAttribute("deptName", this.getDeptName());
 currentRow.setAttribute("deptLocation", this.getDeptLocation());
}

public void copySelectedRow(SelectionEvent selectionEvent) {
 RowKeySet rks = selectionEvent.getAddedSet();
 if (rks != null) {
  System.out.println("Selected Row:");
  RichTable fowTable = (RichTable)selectionEvent.getComponent();
  Iterator iter = rks.iterator();
  while (iter.hasNext()) {
   fowTable.setRowKey(iter.next());
   FacesCtrlHierNodeBinding rowData = (FacesCtrlHierNodeBinding)fowTable.getRowData();
   this.setDeptNo(rowData.getAttribute("deptNo").toString());
   this.setDeptName(rowData.getAttribute("deptName").toString());
   this.setDeptLocation(rowData.getAttribute("deptLocation").toString());
  }
 }
}
Open the index.jspx page and follow the below steps:

  • From data control palette drag and drop populateBean->DeptBean->Table as ADF Table, set RowSelection as "single". 
  • Surround the Table with af:panelCollection component and  has a toolbar facet to which a a single toolbar button is added to initiate the "Copy Row". The button ID is referenced in the table's "partialTrigger" property so that clicking the button initiates a table refresh
  • Map the "Copy Row" ActionListener to "#{viewScope.IndexBean.populateCopyRow}" 
  • Bind the table selectionListener to "#{viewScope.IndexBean.copySelectedRow}"
  • Go to the page bindings and Create Action Binding as show below.

No comments:

Post a Comment