Monday, June 11, 2012

Creating a new row and create auto focus

Hi,

In this post, I am going to explain about adding a new line in a table and auto focus on the new line created.

I have already created an Entity object EmployeesEO based on Employees table from hr schema and a view object EmployeesVO based on an Entity Object which was already created - EmployeesEO. Also created is an Application module with the EmployeesVO instance in it. There should be a page where we perform the demo. So, I have created a jspx page named tableSelectionPage.jspx and dragged the EmployeesVO onto it and created an ADF Table where I haven't enabled sorting or filtering.




Create a Panel Header and drag the table into the Panel Header and created two toolbar buttons in a toolbar.

I have labelled them "New Line" and "New Line Programatically".

I have created a CreateInsert onto New Line button. And another method - createRowProgramatically to create a new line on the UI programatically.

So, now let me explain the scenario. Ideally, when we use CreateInsert method to create a new line, it would create a new line on top of all the rows displayed existing in the table. Below figure explains it.



There was a requirement for my project where in you need to create a new line below the existing lines. So, you would ideally need to take the VO Iterator handle and check for the number of rows and create a new line below all the lines. Code written on "New Line Programatically" handles this requirement. Not to worry, I have provided the code for doing so, in the end of this post. Here is the screenshot, how the line is displayed after all the existing lines.



This works irrespective of whichever line you select, it would always create a new line below all the lines. You make use of the following line to create in such a way.

vo.insertRowAtRangeIndex(vo.getRangeIndexOf(vo.last()) + 1, newRow);

But, there is a problem involved in this. If you can clearly observe the above screenshot. The focus is on the line selected earlier. But, a new line is still created after all the existing rows which is quite wrong, as ideally, if a new line is created, the focus should be on the new line created. You can observe this in the second screenshot as the focus is on the new line created using CreateInsert of the View Object. There are a few bugs occurred due to this.

  • 1. When you click "New Line Programatically" button, and then click on "Delete" button, then the last line will be deleted, even if for the end user, it appears that a different line is selected and that should be deleted. 
  • 2.  And eventually if you keep on pressing "Delete" button, all the last lines would be keep on deleting instead of deleting the line selected. This happens because, on the UI even though it appears another line has been selected, internally it is the last line on which the focus is on.

We can overcome this by using the following line of code, where the UI focus will be on the row selected, and internally, the same row would be selected.

boolean flag= vo.setCurrentRowAtRangeIndex(vo.getRangeIndexOf(vo.last()));


And last, here is the code for managed bean used for creating the new row programatically.


package com.fcspoc.adf.ui.bean;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.context.AdfFacesContext;

import oracle.jbo.Row;
import oracle.jbo.server.ViewObjectImpl;

public class TableSelectionAppBean {
    private RichTable empTable;

    public TableSelectionAppBean() {
    }

    public void createRowProgramatically(ActionEvent actionEvent) {
        // Add event code here...
        try {
            DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            DCIteratorBinding iterBind = (DCIteratorBinding)dcBindings.get("EmployeesVOIterator");
            ViewObjectImpl vo = (ViewObjectImpl)iterBind.getViewObject();
            Row newRow = vo.createRow();
            vo.insertRowAtRangeIndex(vo.getRangeIndexOf(vo.last()) + 1, newRow);
            boolean flag= vo.setCurrentRowAtRangeIndex(vo.getRangeIndexOf(vo.last()));
            AdfFacesContext.getCurrentInstance().addPartialTarget(this.getEmpTable());
        } catch (Exception e) {
            System.out.println("In Exception block in createLinesRow method in new line button");
            e.printStackTrace();
            FacesMessage msg =
                new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "System is unable to process the invoice. Please try re-processing the invoice or contact the System Administrator");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void setEmpTable(RichTable empTable) {
        this.empTable = empTable;
    }

    public RichTable getEmpTable() {
        return empTable;
    }
}

You can get the sample application here. Feel free to post questions/ feedback on this. Good bye for now  :)

No comments:

Post a Comment