Thursday, May 22, 2014

Using Sequence in ADF

The mentioned example demonstrates a scenario where EmployeeID attribute is supposed to be populated from sequence names emp_seq

1. Make sure that the EntityIMPL class has been defined for the entity to be used(EmployeeEO in this case)

2. Over ride the create method as follows:




    /**
     * Add attribute defaulting logic in this method.
     * @param attributeList list of attribute names/values to initialize the row
     */
    protected void create(AttributeList attributeList) {
        super.create(attributeList);
        setEmployeeId(nextSequenceVal("EMP_SEQ"));
    }


    public Number nextSequenceVal(String seqName){
        SequenceImpl seq=new SequenceImpl(seqName,getDBTransaction());
        System.out.println("seqence no "+seq.getSequenceNumber()+"  "+seq.getSequenceNumber());
        return seq.getSequenceNumber();
    }

3. Use the corresponding VO as required on the jspx page

Tuesday, May 20, 2014

Get the new row of the ADF table while using insert operation

If you need to fetch the values of the new row being inserted to editable adf table, use following in the backing bean:


            CollectionModel tableModel = (CollectionModel) getEmployee().getValue();
            JUCtrlHierBinding adfModel = (JUCtrlHierBinding) tableModel.getWrappedData();
            DCIteratorBinding dciter = adfModel.getDCIteratorBinding();
            ViewObject voTableData = dciter.getViewObject();
            Row rowSelected = voTableData.getCurrentRow();
            String fName="";
            if(rowSelected.getAttribute("FirstName")!=null){
                fName=(String)rowSelected.getAttribute("FirstName");
                System.out.println(fName);
            }



getEmployee() : binding for the table
FirstName : the column of table 

Monday, May 19, 2014

Get the current selected row of af:table

In order to get the selected row attributes of af:table, follow these steps:


1. Bind the selectionListener property to a java method as:

<af:table value="#{bindings.EmployeesVO1.collectionModel}" var="row"
                  rows="#{bindings.EmployeesVO1.rangeSize}"
                  emptyText="#{bindings.EmployeesVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
                  fetchSize="#{bindings.EmployeesVO1.rangeSize}"
                  rowBandingInterval="0"
                  selectedRowKeys="#{bindings.EmployeesVO1.collectionModel.selectedRow}"
                  selectionListener="#{EmployeeEdit.employeeSelectListener}"
                  rowSelection="single" id="t1">

2. Define the selectionListener in managed bean as:

    public void employeeSelectListener(SelectionEvent selectionEvent) {
        System.out.println("Selection event called");
     
        DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        DCIteratorBinding dcItteratorBindings =bindings.findIteratorBinding("EmployeesVO1Iterator");
        GenericTableSelectionHandler.makeCurrent(selectionEvent);
        // Get an object representing the table and what may be selected within it
        ViewObject voTableData = dcItteratorBindings.getViewObject();
        
        // Get selected row
        Row rowSelected = voTableData.getCurrentRow();
        if(rowSelected.getAttribute("EmployeeId")!=null){
            System.out.println("Employee selecetd"+rowSelected.getAttribute("EmployeeId")+"    "+rowSelected.getAttribute("FirstName"));   
        }
    }


3. You need to create a custom class that would point the selection event to the current row, else no matter what is the selection the 1st row would be returned. Code for makeCurrent is as follows:

    public static void makeCurrent( 
    SelectionEvent selectionEvent){ 
    
    RichTable _table = (RichTable) selectionEvent.getSource(); 
    //the Collection Model is the object that provides the 
    //structured data 
    //for the table to render 
    CollectionModel _tableModel = (CollectionModel) _table.getValue(); 
    //the ADF object that implements the CollectionModel is 
    //JUCtrlHierBinding. It is wrapped by the CollectionModel API 
    JUCtrlHierBinding _adfTableBinding = (JUCtrlHierBinding) _tableModel.getWrappedData(); 
    //Acess the ADF iterator binding that is used with 
    //ADF table binding 
    DCIteratorBinding _tableIteratorBinding = _adfTableBinding.getDCIteratorBinding(); 
    
    //the role of this method is to synchronize the table component 
    //selection with the selection in the ADF model 
     Object _selectedRowData = _table.getSelectedRowData(); 
     //cast to JUCtrlHierNodeBinding, which is the ADF object 
     //that represents a row 
     JUCtrlHierNodeBinding _nodeBinding = 
     (JUCtrlHierNodeBinding) _selectedRowData; 
     //get the row key from the node binding and set it 
     //as the current row in the iterator 
     Key _rwKey = _nodeBinding.getRowKey(); 
     _tableIteratorBinding.setCurrentRowWithKey( 
     _rwKey.toStringFormat(true)); 
     } 

4. Run the code to see the output:





Tuesday, May 13, 2014

How to access the selected value in af:selectonechoice

Common problem with af:selectonechoice component is when trying to get the selected value it returns the index of the selected item.

I found a turn around for it. It can be done in multiple ways, one of which is explained here.

1. Make sure the attribute which is expected to be selected is defined in the page def as. For example, on the select of department i would like to fetch the location of the selected department:



2. Add the following code in vcl:

    public void deptVCL(ValueChangeEvent valueChangeEvent) {
        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();
        AttributeBinding applicationNameBinding =   (AttributeBinding)bindings.getControlBinding("LocationId");
        String locatriondId= applicationNameBinding.getInputValue().toString();
        System.out.println("Old Location name   "+locatriondId);
        FacesContext contxt = FacesContext.getCurrentInstance();
        valueChangeEvent.getComponent().processUpdates(contxt);
        locatriondId = applicationNameBinding.getInputValue().toString();
        System.out.println("New Location name     " + locatriondId);
    }

3. The output in console is as follows:






populate af:table based on value selected from dropdown : using operation binding

In previous example, i demonstrated how to use parametrized query to populate the the adf table. Here i will achieve the same using operation binding

1. Create 2 view objects:
       a. DepartmentVO : select * from departments

         b. EmployeeDeptVO : select * from employee where department_Id-:dept where dept is a bind variable. Make sure to create its impl class

3. create following custom method in AppmodImpl:
 
 public void getEmployeeForDept(String deptId){
        ViewObjectImpl vo = (ApplicationRoleVOImpl)findViewObject("EmployeeDeptVO1");
        vo.setNamedWhereClauseParam("dept", deptId);
        vo.executeQuery();
    }

and add this method in the page def of the jspx

   

4. On jspx, drag and drop the departnmentvo as selectone choice component

make sure to use department name as display attribute

5. drag and drop the EmployeeDeptVO as adf table on page 

6. create attribute binding on the page def for departmentId(using this we can get the value selected in dropdown)



7. write following line in vcl of the drop down

        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();
        FacesContext contxt = FacesContext.getCurrentInstance();
        valueChangeEvent.getComponent().processUpdates(contxt);
        AttributeBinding applicationNameBinding =   (AttributeBinding)bindings.getControlBinding("DepartmentId");
        String DepartmentId= applicationNameBinding.getInputValue().toString();
        DepartmentId = applicationNameBinding.getInputValue().toString();
        System.out.println("DepartmentId Selected    " + DepartmentId);


        oracle.adf.model.OperationBinding op = (oracle.adf.model.OperationBinding)getBindings().get("getEmployeeForDept");
        op.getParamsMap().put("deptId", DepartmentId);
        Object result = op.execute();
        AdfFacesContext.getCurrentInstance().addPartialTarget(getEmployeeTable());

8. Once the application is run the table is populated based on the department selected in the department drop down




Monday, May 12, 2014

populate af:table based on value selected from dropdown : Query with Paramenter

This demonstration is a simple example, where an adf table dynamically changed based on some value selected from select on choice.
This example is based on HR schema, where value selected in department dropdown, populates the table which contains list of employee belonging to that department
 It can be done in multiple ways, i'll be demonstrating in 2 ways here.
This blog covers the option where it is done by using paramentrized query.

1. Create 2 view objects:
       a. DepartmentVO : select * from departments

       b. EmployeeDeptVO : select * from employee where department_Id-:dept where dept is a bind variable

2.in data control palatte, look out for Execute with param under EmployeeDeptVO

3. drag n drop the dept on jspf page as single selection


Make sure to add the departmentVO1 as list of data source and also change the display name to Department Name

4. Now drag and drop the ExecutewithParams from datacontrol palette on page as adf button(or as desired)

5. Once this is done, its time to select the EmployeeDeptVO on page as adf table with desired attributes:



6. Run the application and there you have a page, where on selecting the department id from drop down, all the employees of the department can be seen






Tuesday, May 6, 2014

Populate checkbox in adf application using the data binding

Populate  checkbox in adf application using the data binding

I was finding using checkbox in adf application using the data binding a bit tricky.
For eg : suppose a field from database name IsApp has value populated as 0/1. When using the binding to populate it value by using the following code:

<af:selectBooleanCheckbox value="#{bindings.IsApp.inputValue == 1}"
                                            label="Is Application" >
</af:selectBooleanCheckbox>

It was successful but i found that it would bring up a checkbox as readonly on the page. while inspecting the element, i found that the source code behind the element as:
<div id="j_id_id5:j_id_id14:0:j_id_id16__xc_c" class="x2e"><img src="/ComplexInsert-ViewController-context-root/adf/images/checkrn.gif" width="12" height="12" border="0" title="Read only Checkbox Not Checked" alt="Read only Checkbox Not Checked"></div>

So, i advise to do following:
1. Create a transient attribute in VO:



Make sure to use the type as boolean and select the updateable property as Always

2. Create a rowImpl class corresponding to the VO if not already created

3. Configure the getter setter of the transient attribute as mentioned below:

    /**
     * Gets the attribute value for the calculated attribute IsAppBoolean.
     * @return the IsAppBoolean
     */
    public Boolean getIsAppBoolean() {
        if (this.getIapp() != null) {
            if (this.getIapp().toString().equals("1")) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * Sets <code>value</code> as the attribute value for the calculated attribute IsAppBoolean.
     * @param value value to set the  IsAppBoolean
     */
    public void setIsAppBoolean(Boolean value) {
        if(value){
            setIsapp(new BigDecimal(1));
        }else{
            setIsapp(new BigDecimal(0));
        }
    }
Note: when getter is called , its value is decided based on the value of IsApp and setter overrides the value os IsApp.


4. Using the Transient Attribute on jspx:
     while using the drag n drop method the isAppBoolean attribute is defaulted as type outputext in case of readonly table and input text in case of updatable form, Either you can right click on the component and use convert option to convert it into checkbox or you may use this:

        a. Readonly Table  :
                                      <af:column sortProperty="ISAPPBOOLEAN" sortable="false"
                                         width="75" headerText="IsAPP" id="c6">
                                                   <af:selectBooleanCheckbox selected="#{row.ISAPPBOOLEAN}"
                                                     id="sbc1"/>
                                             </af:column>

         b. Updatable form :
                                        <af:selectBooleanCheckbox value="#{bindings.ISAPPBOOLEAN.inputValue}"
                                            label="IsApp"
                                            id="sbc2">