Wednesday 5 December 2012

8. Create and Update Page in OAF

Here are the steps for creating 'Employee create update' page. I have modified the search page created in previous post.

1) Create a new Entity Object (EO):
===================

Right click on 'emprec' package and create a new entity object (This will open a wizard having 5 steps).

Step 1
        Package: xxcus.oracle.apps.fnd.emprec.schema.server
        Name: XxEmployeeEO
        Schema Object (in Database Object): EMPLOYEE
        Click Next.

Step 2
        Keeps default (all attributes selected). Click Next.

Step 3
        If there is any primary key in DB table, then keep all defaults else select a primary key (like empno). Click Next.

Step 4
       Keep defaults and click on Next.

Step 5
       Keep 'Generate Default View Object' uncheked and click on Finish.

2) Create a new View Object (VO) based on EO created in (1):
====================
Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
        Package: xxcus.oracle.apps.fnd.emprec.server
        Name: XxEmployeeVO
       Choose the radio button 'Updatable access through Entity Objects'. Click Next.

Step 2
     Select the xxcus.oracle.apps.fnd.emprec.schema.server.XxEmployeeEO from 'Available' list and shuttle it to 'Selected' list. Click Next.

Step 3
     Move all the columns except WHO columns (lastUpdateLogin, createdBy...) to 'Selected' list from 'Available' list attributes.
Click Next.

      Keep defaults for step 4, 5 & 6.

Step 7
      Select check boxes for 'Generate Java File' for both 'View Object Class' and 'View Row Class'. Click Finish.

Double Click on XxEmployeeAM and shuttle XxEmployeeVO from 'Available view objects' to 'Data Model'.
(now there are two VO instances in AM :XxEmployeeSearchVO1 & XxEmployeeVO1).

3) Edit Employee Search Page (XxEmployeeSearchPG):
====================
(This includes adding a 'create button' at top & 'update' icon on every row in search result. Modified page will appear as below:).




















Step 1
Right click on pageLayoutRN and add a new region. Set properties as below:
        Region Style: pageButtonBar
        ID: pageBtnBarRN
        
        Right click on pageBtnBarRN region and add a new item:
              Item Style: submitButton
              ID: createBtn
              Prompt: Create Employee

Step 2
Right click on XxEmployeeSearchVO1 table region and add an item. Set the below properties:
              Item Style: Image
              ID: updateImg
              Prompt: Update
              Image URI: updateicon_enabled.gif
              Action Type: fireAction
              Event: updateEvent
              Parameters: it will open a new window. Add a parameter as below:
                 Name: p_empNum value: ${oa.XxEmployeeSearchVO1.Empno}

4) Create a new Update Create page:
====================
(Here user can either create a new employee or can update existing one. The page will appear as shown below: ).



















Right click emprec --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will open a popup window)
We are creating Employee Create Update Page, so specify the details of page as below:
          Name: XxEmployeeCreateUpdatePG
          Package: xxcus.oracle.apps.fnd.emprec.webui

Create a new region under pageLayout of type 'header'

Create another region under the header region using wizard
(This will open a wizard window having 4 steps):

  • Select 'XxEmployeeAM' from Application Module drop down and select 'XxEmployeeVO1' in available view usages. Click Next.
  • Choose region style as 'defaultSingleColumn' from drop down. Click Next.
  • Shuttle all the fields from available to selected attributes. Click Next.
  • Change the style to messageStyledText for Empno and messageTextInput for other remaining rows. Also modify the prompt to make it more user friendly (like empName to Employee Name).
  • Click Next and finish.

Right click on pageLayoutRN and add a new region

Set properties as below:
        Region Style: pageButtonBar
ID: pageBtnBarRN

Right click on pageBtnBarRN region and add 2 new items of type submitButton:
Item Style: submitButton
ID: saveBtn;  ID: cancelBtn
prompt: Save; prompt: Cancel

Now change the properties for each field from property inspector as shown below:

pageLayout: ID: pageLayoutRN
                 AM Definition: xxcus.oracle.apps.fnd.emprec.server.XxEmployeeAM
                 Window Title: Employee Create Update Page
                 Title: Employee Create Update

header:      ID: empCreateRN

5) Create a new controller for Update Create page:
====================
Step 1
Select XxEmployeeCreateUpdatePG in navigator tab. Declarative form of page will be visible in structure tab.

Step 2
Right click on pageLayout region --> set new controller (This will open a popup window). Enter the below details:
       package Name: xxcus.oracle.apps.fnd.emprec.webui
       Class Name: XxEmployeeCreateUpdateCO
  
The declarative page structure in jDev will be similar to as shown below:



6) Code for Performing Create & Update Operation
====================

  • Catch the 'create button' or 'Update' event in PFR method of XxEmployeeSearchCO (controller of XxEmployeeSearchPG page) and navigate to 'Employee Create Update Page' (XxEmployeeCreateUpdatePG). We also pass a token (in the form of HashMap) to indicate whether it is a create or update operation.
// XxEmployeeSearchCO :: PFR
if (pageContext.getParameter("createBtn") != null) {
    HashMap hm = new HashMap(); //com.sun.java.util.collections.HashMap;
    hm.put("event", "create");
pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps/
fnd/emprec/webui/XxEmployeeCreateUpdatePG", 
null, (byte)0, null, hm, false, null);
}

if ("updateEvent".equals(pageContext.getParameter(EVENT_PARAM))) {
    String p_empNum = pageContext.getParameter("p_empNum");
    HashMap hm = new HashMap();
    hm.put("event", "update");
    hm.put("empNum", p_empNum);
pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps/
fnd/emprec/webui/XxEmployeeCreateUpdatePG", 
null, (byte)0, null, hm, false, null);
}
  • Once navigated to create page, we have to initialize the XxEmployeeVO1, so data entered by user in the fields can be mapped to its attributes. And in case of 'update', populate the records for the employee. We write this code in PR method of XxEmployeeCreateUpdateCO (controller of XxEmployeeCreateUpdatePG page). First we check if it is create or update event and will call a method from AM accordingly:
// XxEmployeeCreateUpdateCO :: PR method
public void processRequest(OAPageContext pageContext, OAWebBean webBean) {
    super.processRequest(pageContext, webBean);
    am = pageContext.getRootApplicationModule();

    if ("create".equals(pageContext.getParameter("event"))) {
        am.invokeMethod("initCreateEmp");
    }

    if ("update".equals(pageContext.getParameter("event"))) {
        String empNum = pageContext.getParameter("empNum");
        Serializable[] param = { empNum };
        am.invokeMethod("initUpdateEmp", param);
    }
}

Write below methods in XxEmployeeAMImpl.java file:

// XxEmployeeAMImpl :: 
public void initCreateEmp() {
    try {
  XxEmployeeVOImpl empCreateVO = getXxEmployeeVO1();
  empCreateVO.setMaxFetchSize(0);
  XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)empCreateVO.createRow();

// here we are setting the employee number using a DB Sequence
  Number empNum = getOADBTransaction().getSequenceValue("EMPLOYEE_NUMBER_S");
  row.setEmpno(empNum);
  empCreateVO.insertRow(row);
  row.setNewRowState(Row.STATUS_INITIALIZED);
 } catch () {
  e.printStackTrace();
  }
}

public void initUpdateEmp(String empNum) {
    try {
  XxEmployeeVOImpl employeeVO = getXxEmployeeVO1();
  employeeVO.setWhereClause(null);
  employeeVO.setWhereClauseParams(null);
  employeeVO.setWhereClause("EMPNO = :1");
  employeeVO.setWhereClauseParam(0, empNum);
  employeeVO.setMaxFetchSize(-1);
  employeeVO.executeQuery();
  } catch (Exception e) {
   e.printStackTrace();
   }
}

Finally, user can click on 'Save' button to commit the data or 'Cancel' to return back to search page.
  • We will catch the 'save' or 'cancel' button click in PFR method of XxEmployeeCreateUpdateCO and call a method from AM accordingly:

// XxEmployeeCreateUpdateCO :: PFR method
public void processFormRequest(OAPageContext pageContext, 
                               OAWebBean webBean) {
    super.processFormRequest(pageContext, webBean);

    OAApplicationModule am = pageContext.getRootApplicationModule();

    if (pageContext.getParameter("cancelBtn") != null) {
   pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps
   /fnd/emprec/webui/XxEmployeeSearchPG", null, (byte)0, null, null, false, null);
    }

    if (pageContext.getParameter("saveBtn") != null) {
    
 /*Here we are performing commit operation 
   and returning back to search page. 
   Also we are fetching the updated/created 
   emp num so we can display a message on search page*/
   
  String savedEmp = am.invokeMethod("commit").toString();
        HashMap hm = new HashMap();            
        hm.put("updated", "Y");
        hm.put("empUpdated", savedEmp);
   pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps
   /fnd/emprec/webui/XxEmployeeSearchPG", null, (byte)0, null, hm, false, null);
    }
}

Below is 'commit' method created in AMImpl class:

public String commit() {
    try {
  XxEmployeeVOImpl employeeVO = getXxEmployeeVO1();
  XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)employeeVO.first();
  String savedEmp = row.getEmpno().toString();
  getOADBTransaction().commit();
  return savedEmp;
  } catch (Exception e) {
   e.printStackTrace();
   }
}
Below is code to display successful message on search page:
// XxEmployeeSearchCO :: PR method
public void processRequest(OAPageContext pageContext, OAWebBean webBean) {
    super.processRequest(pageContext, webBean);

    if ("Y".equals(pageContext.getParameter("updated"))) {
        String updatedEmp = pageContext.getParameter("empUpdated");
        throw new OAException("Employee Number " + updatedEmp + 
                              " has been saved successfully.", 
                              OAException.CONFIRMATION);
    }

}


Message will be displayed after saving the data as shown below:























14 comments:

  1. hi shshant.
    i tried your example. when you navigate to the original page, i get http 400 when it is deployed to the server. On local machine it works correctly.
    anythoughts?

    ReplyDelete
  2. Hi,
    I implement the search ,create and update page. I also created a External LOV.
    I attached this lov to search and create page, its working fine on search page but LOV is not popping out when i click on magnifying glass on create page.

    I found this error described here(Unanswered) : https://community.oracle.com/thread/2559600

    Any insight would be helpful.

    ReplyDelete
  3. Hi sushant
    I tired your Example of create and updatepage.while runing the page i am getting error..Error(68,19): method does not return a value...This is the error i am facing..Could you give me Solution..

    ReplyDelete
    Replies
    1. Are you getting this error on commit() method ?
      Try using this code:

      public String commit() {
      String savedEmp;
      try {
      XxEmployeeVOImpl employeeVO = getXxEmployeeVO1();
      XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)employeeVO.first();
      savedEmp = row.getEmpno().toString();
      getOADBTransaction().commit();

      } catch (Exception e) {
      e.printStackTrace();
      }
      return savedEmp;
      }

      Delete
  4. Hi Sushant,

    After declaring a method which u have sent recenlty...Geting the error Saverec not have been declared...

    Error(79,13): variable savedRec might not have been initialized

    i Have initialize the variable savedRec ...

    if (pageContext.getParameter("Save") != null) {

    /*Here we are performing commit operation
    and returning back to search page.
    Also we are fetching the updated/created
    OrgId Detials so we can display a message on search page*/

    String savedRec = am.invokeMethod("commit").toString();
    HashMap hm = new HashMap();
    hm.put("updated", "Y");
    hm.put("RecUpdated", savedRec);
    pageContext.forwardImmediately("OA.jsp?page=/DEMOTest/oracle/apps/fnd/hello/webui/SearchPG",
    null, (byte)0, null, null, false, null);..

    ReplyDelete
  5. Hi Sushant,

    I have resolved the on this...Error(79,13): variable savedRec might not have been initialized


    public String commit() {
    String savedRec= null;
    try {
    CreateUpdateVOImpl CreateUpdateVO = getCreateUpdateVO1();
    CreateUpdateVORowImpl row = (CreateUpdateVORowImpl)CreateUpdateVO.first();
    savedRec= row.getOrgId().toString();
    getOADBTransaction().commit();

    } catch (Exception e) {
    e.printStackTrace();
    }
    return savedRec;
    }

    ReplyDelete
  6. Hi Sushant,

    Thanks Sushant..The Code is working Fine.

    But i am facing small issue..

    Search Page Result working Fine...When i Click on Update image button The Records Firing on the page...when i click on the save and cancel buttons it is not rendering the back to page..

    Code is written in Processes From Request for save and cancel buttons.

    if (pageContext.getParameter("Cancel") != null) {
    pageContext.forwardImmediately("OA.jsp?page=/DEMOTest/oracle/apps/fnd/hello/webui/SearchPG",
    null, (byte)0, null, null, false, null);
    }



    if (pageContext.getParameter("Save") != null) {

    String savedRec;
    savedRec = am.invokeMethod("commit").toString();
    HashMap hm = new HashMap();
    hm.put("updated", "Y");
    hm.put("RecUpdated", savedRec);
    pageContext.forwardImmediately("OA.jsp?page=/DEMOTest/oracle/apps/fnd/hello/webui/SearchPG",
    null, (byte)0, null, null, false, null);
    }



    ReplyDelete
  7. This is the error on CreateUpdatePage ..


    Error




    The window title attribute for the page layout region has not been set. This attribute value will be used for the browser window title and should be set according to the UI standards. A default window title will be displayed for all such pages that violate the standards. Action: Set the window title or title attribute for the page layout region. The title attribute is used as a secondary source for the window title if the window title is missing.

    ReplyDelete
  8. Dear Sushant,

    Thanks for this excellent blog, it really helps big times.

    I followed your example and tried to get a LOV on the second Page (Create Employee Page). But this LOV never works, it just doesn't pop out.

    Any suggestions , please.

    ReplyDelete
    Replies
    1. What steps you followed for creating LOV ?
      Also, you can refer this
      http://sushantsharmaa.blogspot.in/2012/12/10-dependent-lov-in-oaf.html

      Delete
    2. Dear Sushant,

      Thanks for the reply.

      I have created an item of type "messageLovInput", created the LOV mappings. The strange thing is if i place a LOV item on the first screen I do get to see the pop-up LOV window with the settings I have mentioned. And if I run the second page, I mean from OAF without clicking on update icon, I get to see the pop-up window.

      Much appreciate your response and assistance. Looking forward to your warm response.

      Delete
  9. Hi Sushant,

    Excellent blog, this helps a lot.

    Just want to know the purpose of creating EO here, since create and update is done through VO here.

    Thanks,
    Nupur Garg

    ReplyDelete
    Replies
    1. Hi Nupur,

      For performing any DML operation, we have to create entity object. After that, we create view objects based on these entity objects.

      --Sushant

      Delete
  10. Hi Sushant

    I have created a page which can be used for both insert and update. there is a field with an lov (created an internal lov). this lov works properly on create page but the window never opens on update page. Could you please let me know how to resolve this?

    Thanks

    ReplyDelete