Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label Current Row. Show all posts
Showing posts with label Current Row. Show all posts

Monday, 7 April 2014

Get updated model values in value change listener instantly, ProcessUpdates in ADF (a beauty)

Hello All,

This posts talks about updating model instantly when a attribute is changed on page level.
In ValueChangeListener of component if we try to get new value from Model layer, it always returns old value, then we have only one option to get new value, use event object (evt.getNewValue();)
but sometimes we need to update model same time
So how to do this-

  • Created a Fusion Web Application using Departments table of HR Schema (Oracle)


  • Dropped Departments Vo on page as a form, and created ValueChangeListener on DepartmnetName field to get new value 





  • Now i have written a code to get DepartmentName from current row of Departments VO (ViewObject) and to get from ValueChangeEvent

  • Method in AMImpl- Called in ValueChangeListener through binding Layer

    /**Method to print Department Name */
        public void getDeptNameAction() {
            ViewObject depart = this.getDepartments1();
            Row curRow = depart.getCurrentRow();
            if (curRow != null) {
                System.out.println("Current Department from model is-" + curRow.getAttribute("DepartmentName"));
            }
        }
    


    Code in ValueChangeListener - AM Method Called and Code to get new value from event itself

        /**Value change listener for Department Name
         * @param vce
         */
        public void deptNmVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                System.out.println("New Value in VCE-" + vce.getNewValue());
                BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry();
                OperationBinding ob = bc.getOperationBinding("getDeptNameAction");
                ob.execute();
            }
        }
    

  • In this case when i have changed value on page 



  • see the result -output from valuechangelistener- Model layer returns old value :-(


  • Now to update value in Model layer , i have just called processUpdates in ValueChangeListener- See the code

  •     /**Value change listener for Department Name
         * @param vce
         */
        public void deptNmVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                //Method to update Model in VCE
                vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
                System.out.println("New Value in VCE-" + vce.getNewValue());
                BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry();
                OperationBinding ob = bc.getOperationBinding("getDeptNameAction");
                ob.execute();
            }
        }
    

  • see the result -Value is updated in model instantly (in VCE)

so this is how processUpdates works, Cheers :-)
See one more post on this concept with different usecase- Update Model Values while Validation (Exception) occurs on page on Value Change event
Happy Learning

Wednesday, 2 April 2014

Performing Partial Rollback (Undo Changes) operation in ADF, Stay on current row after rollback

Hello All ,
This post talks about a common requirement of using partial rollback in ADF

Suppose there is two tables on page Departments and Employees, and i have changed one row in Departments table and same time created a row in Employees table, now i want to rollback the changes done in Departments table only

In this case if i use default Rollback operation then it will not only undo the changes of Department table but also remove the newly created row of Employees table
but this was not my purpose.

So to do this kind of things we can use partial rollback operation
  • I have created a fusion web application (Model & VC) using Departments & Employees Table of Oracle's default HR Schema

  • Now drop departments & employees VO on page with it's default operations (CreateInsert, Delete, Execute, Commit & Rollback) and a button to execute partial rollback of departments ViewObject


  • Here in this example i am creating partial rollback for Departments VO only, so to do this add a new transient attribute in Departments Vo to get current state of each row




  • How to get state of each row , in RowImpl class of departments ViewObject , write this code in getter of transient attribute or see my previous blog-post Identifying Modified/newely added row in af:table, get all modified rows of viewobject in bean

  •     /**
         * Gets the attribute value for the calculated attribute RowStatusTrans.
         * @return the RowStatusTrans
         */
        public Integer getRowStatusTrans() {
            /*here row is reference variable of collection, this expression returns an int value if it is
             2-Modified
             0-New
             1-Unmodified
            -1-Initialized
            */
            byte entityState = this.getEntity(0).getEntityState();
            return new Integer(entityState);
        }
    

  • Have created a method to remove newly added row , and to undo changes in existing rows of departments VO in Impl class

  •     /**Method to revert changes of current row
         * @param curRow
         */
        public void revertChangesCurrentRow(Row curRow) {
            if (curRow != null) {
                curRow.refresh(Row.REFRESH_UNDO_CHANGES | Row.REFRESH_WITH_DB_FORGET_CHANGES);
            }
        }
    
        /**Method to check whether row should be removed or not 
         * If it is new - removed
         * If old one- Undo Changes
         * */
        public void revertOrremoveRowValues() {
            ViewObject deptVo = this;
            RowSetIterator deptIter = deptVo.createRowSetIterator(null);
            while (deptIter.hasNext()) {
                Row nextRow = deptIter.next();
                if (nextRow.getAttribute("RowStatusTrans") != null) {
                    Integer rowStatus = (Integer) nextRow.getAttribute("RowStatusTrans");
                    if (rowStatus == 2) {
                        System.out.println("Modified Rows-" + nextRow.getAttribute("DepartmentId"));
                        revertChangesCurrentRow(nextRow);
                    } else if (rowStatus == 0) {
                        System.out.println("New Row Removed");
                        nextRow.remove();
                    }
                }
            }
            this.executeQuery();
        }
    

  • To read more about REFRESH_UNDO_CHANGES and other constants -http://docs.oracle.com/cd/B14099_19/web.1012/b14022/oracle/jbo/Row.html
  • Exposed this method to client and added it to page bindings then called it on Partial Rollback button


  • After running application, i have changed some rows of Departments table and created a new row in employees table


  • Now if i use rollback, it will also remove the new row of employees table, this is the dis-advantage of using rollback


  • Again i have changed some rows of departments table and created a new row in employees table


  • Now see when i click on partial rollback button, it will only undo changes done in department table and employee table is untouched


  • And to stay on current row after partial rollback operation just remove executeQuery from revertOrremoveRowValues() method
Download Sample App
Cheers :-)  Happy Learning

Thursday, 25 October 2012

Set on Current row after Rollback Execute or page refresh

Some times we edit a table in form and Save(Commit & Execute) or Cancel(Rollback & Execute)  and table refreshed to its first record means focus is now on first row of table.
And we need the same row again, then we search it and perform another operation, this is really disgusting behavior of table for Developer.

To set on previously selected row after execute we can use this code,
in this scenario we have to get current row key from its IteratorBinding and after Execute we can set it again to show that row as selected.





    /**
     * Generic Method to call operation binding
     **/
     public BindingContainer getBindings() {
      return BindingContext.getCurrent().getCurrentBindingsEntry();
     }


     BindingContainer bindings = getBindings();
     //Get Iterator of table
     DCIteratorBinding parentIter = (DCIteratorBinding)bindings.get("IteratorName");
     //Get current row key
     Key parentKey = parentIter.getCurrentRow().getKey();

     //You can add your operation code here, i have used simple Cancel operation 
     //with Rollback and Execute
     
     
     OperationBinding ob= bindings.getOperationBinding("Rollback");
     ob.execute();
     OperationBinding ob1= bindings.getOperationBinding("Execute");
     ob1.execute();
    
     //Set again row key as current row
     parentIter.setCurrentRowWithKey(parentKey.toStringFormat(true));