Tuesday, October 9, 2012

How to Identify a View Object is modified

There are cases where we need to show the modified VO rows in separate pop up window or highlight the modified/new rows .

I have a quiet interesting usecase in my development project and thought i would write about it . The usecase is tat an ADF Table in the ui page can  be modified and new rows can also be created.After modifying some of the rows the user has navigated to some other page without committing the modified data. At this point i need to stop the user and alert him saying that some of the VO rows have been modified.

This is a direct approach and can be done in two ways. Either in the managed bean or in the design time page using expressions.According to ADF new/modified rows will be in cache.

Download the Sample Application and run CatchModifiedRows.jspx page.

we will continues using the workspace which i have been using for the earlier post .
Lets start developing it. Create a jspx page CatchModifiedRows.jspx . Drag and drop EmployeesVO1 on to the page as ADF Table and keep the necessary columns you want.keep a button at the bottom of the ADF table to navigate to some other page.












Create Action Listener for the Next button and name the bean as ModifiedVOBean.java and method as chkmeth. Inside the method get the bindings for the EmployessVO1 .

        DCBindingContainer bindings2 =
            (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
              
        JUCtrlHierBinding obj = (JUCtrlHierBinding)bindings2.findCtrlBinding("EmployeesVO1");
        ViewObject targetVO = obj.getViewObject();


we can get the current status of the view object instance using a method isDirty().

Boolean b = targetVO.getApplicationModule().getTransaction().isDirty();

This gives Boolean value of True/False . If something is modified/created the value will be True else False.



Final piece of code is

    public void chkMeth(ActionEvent actionEvent) {
       
        DCBindingContainer bindings2 =
            (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
              
        JUCtrlHierBinding obj = (JUCtrlHierBinding)bindings2.findCtrlBinding("EmployeesVO1");
        ViewObject targetVO = obj.getViewObject();
        Boolean b = targetVO.getApplicationModule().getTransaction().isDirty();
       FacesMessage msg=null;
        Boolean ev = false;
        if(b!=ev){
        msg=new FacesMessage("Hold on ,you have unsaved data.pls commit before proceeding");
        FacesContext.getCurrentInstance().addMessage(null,msg);
        }

  }


The boolean result  can be evulated against True/False and based on it we can throw a message to the user . Now go to the page and change something in any of the column and click Next. you will get the message.Further  you can customize the implementation the way u want like information in the pop up dialog
and so on.



we can also able to get Entity level status from VO using this code

RowSetIterator rs1 =targetVO.createRowSetIterator(null);
while (rs1.hasNext()) {
  EmployeesVORowImpl r = rs1.next();
  Entity eo = r.getEntity(0);
byte currentState= eo.getEntityState();
if(currentState==EntityImpl.STATUS_NEW .......)
{
 ......
}
}

From design time we can access the row status using the following expression
Expression #{row.row.entities[0].entityState}

Getting the View object in MB and performing operations on it is not a good practice.

2 comments:

  1. Hello.
    Importing ViewObject and ApplicationModule to the View layer is bad practice and breaking MVC pattern.
    One should create this method in a View Object imlementation class and expose it through client interface.

    ReplyDelete
  2. Thanks.. but still the binding layer can be accessed from managed bean

    ReplyDelete