Skip to Content

Sample UME Application using SAPUI5 and SAP Gateway

Last week started working with SAPUI5 beta and found very interesting. After working on some small examples, started thinking about writing a small application using UI5 as frontend and SAP Gateway as service provider. I tried using various controls and really impressed with the easiness of coding. This a small application which shows users details, roles and profiles. I will try to extend the same to create/update/delete users later.

To get started download the Download Evaluation Package for UI Development Toolkit for HTML5.

Though IDE is supported to develop applications, we still don’t have the support to directly create projects. In order to start with new developments we should copy existing sample application ‘getting-started-sample’ and rename it to a new project. Every time you create a new HTML page we need to copy the standard SAPUI5 code, so just to make life a bit easy we can use eclipse feature to create a HTML template file.

Go to Window -> Preferences -> Web -> HTML Files -> Editor -> Templates, then click on New button. Enter Name, Description as SAPUI5 Template and enter the following content in Pattern area:

                                             

So next time you create a new HTML you can see this new option in your HTML templates.

2.JPG

Here is the sample application

The final application looks like this:

1.JPG

I have developed OData service in SAP Gateway based on

‘How To… Create a Gateway Service Using the RFC Generator – Advanced Scenario’ View Document.

The application shows list of available users by calling the Query service. On selection of user in table it calls READ service and shows rest of the data in corresponding tabs.

The frame work provides beautiful options to create your own world 🙂 in coding. We can use many of the built in functions like Shell, ApplicationHeader to create the common header for all pages. I am using the class sap.ui.commons.ApplicationHeader to create common header. The API provides many functions like, you can add Log off function, you can set welcome note, user name, logo etc.

   var appHeader = new sap.ui.commons.ApplicationHeader("userManagementHeader"); //Create Application Header
   appHeader.attachLogoff(function logoffPage(oEvent)  { //attach logoff function, here I am just display a confirmation popup.
  jQuery.sap.require("sap.ui.commons.MessageBox");
     sap.ui.commons.MessageBox.show(
       "Are you sure want to logoff from this page?",
       sap.ui.commons.MessageBox.Icon.INFORMATION,
       "Logoff Confirmation",
       [sap.ui.commons.MessageBox.Action.OK,sap.ui.commons.MessageBox.Action.CANCEL] );   }    );
  
   appHeader.setDisplayLogoff(true);
   appHeader.setDisplayWelcome(true);
   appHeader.setLogoSrc("resources/logo_capgemini.gif");//set up logo path. copy your logo to resources folder in NWDS
   appHeader.setLogoText("Capgemini SAP IDP");
   appHeader.setUserName("Abhilash Gampa");  
   appHeader.placeAt("appBody");

The source for the user data is Gateway service. So create a model to call the Query operation:

     var oModel = new sap.ui.model.odata.ODataModel("http://sapgwserver::8000/sap/opu/odata/sap/Z_UI5_USER_MAINT_CM/");   
     sap.ui.getCore().setModel(oModel); //Set the model at application level.

Then create Table to show list of available users. I will publish all the code at the end, but for explanation purpose I will use only required code here.

     var userDetailsTable = new sap.ui.table.DataTable({
   title : "Available Users",
   width : "75%",
   visibleRowCount : 5,
   ExpandedVisibleRowCount : 20,
   selectionMode : sap.ui.table.SelectionMode.Single,
   editable : false
  });
 
  //Add all columns
     userDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: "Last Name"}),
        template: new sap.ui.commons.TextField().bindProperty("value", "lastname"),
        sortProperty: "lastname" }));
   
  //on select of record call the ODATA READ service and show more details about user.
     userDetailsTable.attachRowSelect(function(oEvent)
     {
      var currentRowContext = oEvent.getParameter("rowContext");
      var selectedUserID = oModel.getProperty("username", currentRowContext);
 //Here I am using datajs API to call the READ operation and setting the values to individual UI elements.
   OData.read("http://sapgwserver:8000/sap/opu/odata/sap/Z_UI5_USER_MAINT_CM/z_ui5_user_maintCollection('"+selectedUserID+"')",
   function (response)
   {     
     sap.ui.getCore().getControl("title_cb_m").setValue(response.title_p);
     sap.ui.getCore().getControl("firstname_tf_m").setValue(response.firstname);
     sap.ui.getCore().getControl("lastname_tf_m").setValue(response.lastname);
     sap.ui.getCore().getControl("language_tf_m").setValue(response.language);
     sap.ui.getCore().getControl("department_tf_m").setValue(response.department);
     sap.ui.getCore().getControl("telephone_tf_m").setValue(response.telephone);
     sap.ui.getCore().getControl("e_mail_tf_m").setValue(response.e_mail);
     sap.ui.getCore().getControl("country_cb_m").setValue(response.country);
     sap.ui.getCore().getControl("city_tf_m").setValue(response.city);
      });
      userProfileDetailsTable.bindRows(currentRowContext+"/profiles_r");//(You can use the below syntax also)
  //userProfileDetailsTable.bindRows("z_ui5_user_maintCollection('"+selectedUserID+"')"+"/profiles_r");
// The beauty is, you need not to map individual columns. Based on the value field mapping table column and fields in OData service it automatically maps the data. 
  userRolesDetailsTable.bindRows(currentRowContext+"/activitygroups_r");//(You can use the below syntax also)
      //userRolesDetailsTable.bindRows("z_ui5_user_maintCollection('"+selectedUserID+"')"+"/activitygroups_r");
 
userDetailsTable.bindRows("z_ui5_user_maintCollection"); //Bind the operation to main table rows, so it calls Query operation and binds the data to table.

Similarly create a form for User Personal Details and tables for Roles, Profiles.

Now create three tabs for Personal , Roles and Profile details and assign the content. The data is already mapped in the above steps using bindRows for table.

     var userTab = new sap.ui.commons.Tab().setText("Person").addContent(moreUserDetailsLayout);
      var profilesTab = new sap.ui.commons.Tab().setText("Profiles").addContent(userProfileDetailsTable);
      var rolesTab = new sap.ui.commons.Tab().setText("Roles").addContent(userRolesDetailsTable);
      var tabStrip =  new sap.ui.commons.TabStrip({width:"75%"}).addTab(userTab).addTab(rolesTab).addTab(profilesTab);

View the full code below and the roles tab looks like:

3.JPG

Here is the full code:

<!DOCTYPE html>
<html><head>
    <meta http-equiv=’X-UA-Compatible’ content=’IE=edge’ />
    <title>SAP Flight Management</title>

    <script id=’sap-ui-bootstrap’ type=’text/javascript’
        src=’./resources/sap-ui-core.js’
        data-sap-ui-theme=”sap_goldreflection”
        data-sap-ui-libs=’sap.ui.commons,sap.ui.ux3,sap.ui.table’></script>

    <script type=”text/javascript”>
    <!–

   var appHeader = new sap.ui.commons.ApplicationHeader(“userManagementHeader”);
   appHeader.attachLogoff(function logoffPage(oEvent)
   {
  jQuery.sap.require(“sap.ui.commons.MessageBox”);
     sap.ui.commons.MessageBox.show(
       “Are you sure want to logoff from this page?”,
       sap.ui.commons.MessageBox.Icon.INFORMATION,
       “Logoff Confirmation”,
       [sap.ui.commons.MessageBox.Action.OK,sap.ui.commons.MessageBox.Action.CANCEL]            
   );   }   );
  
   appHeader.setDisplayLogoff(true);
   appHeader.setDisplayWelcome(true);
   appHeader.setLogoSrc(“resources/logo_capgemini.gif”);
   appHeader.setLogoText(“Capgemini SAP IDP”);
   appHeader.setUserName(“Abhilash Gampa”);
  
     appHeader.placeAt(“appBody”);
     var oModel = new sap.ui.model.odata.ODataModel(“http://sapgwserver:8000/sap/opu/odata/sap/Z_UI5_USER_MAINT_CM/“);   
     sap.ui.getCore().setModel(oModel);

     var userDetailsTable = new sap.ui.table.DataTable({
   title : “Available Users”,
   width : “75%”,
   visibleRowCount : 5,
   ExpandedVisibleRowCount : 20,
   selectionMode : sap.ui.table.SelectionMode.Single,
   editable : false
  });
        
     userDetailsTable.addColumn(new sap.ui.table.Column({
       label: new sap.ui.commons.Label({text: “User ID”}),
       template: new sap.ui.commons.TextField().bindProperty(“value”, “username”),
       sortProperty: “username” }));
             
     userDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: “First Name”}),
        template: new sap.ui.commons.TextField().bindProperty(“value”, “firstname”),
        sortProperty: “firstname” }));

     userDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: “Last Name”}),
        template: new sap.ui.commons.TextField().bindProperty(“value”, “lastname”),
        sortProperty: “lastname” }));   

     userDetailsTable.attachRowSelect(function(oEvent)
     {
      var currentRowContext = oEvent.getParameter(“rowContext”);
      var selectedUserID = oModel.getProperty(“username”, currentRowContext);

   OData.read(“http://sapgwserver:8000/sap/opu/odata/sap/Z_UI5_USER_MAINT_CM/z_ui5_user_maintCollection(‘”+selectedUserID+”‘)”,
   function (response)
   {     
     sap.ui.getCore().getControl(“title_cb_m”).setValue(response.title_p);
     sap.ui.getCore().getControl(“firstname_tf_m”).setValue(response.firstname);
     sap.ui.getCore().getControl(“lastname_tf_m”).setValue(response.lastname);
     sap.ui.getCore().getControl(“language_tf_m”).setValue(response.language);
     sap.ui.getCore().getControl(“department_tf_m”).setValue(response.department);
     sap.ui.getCore().getControl(“telephone_tf_m”).setValue(response.telephone);
     sap.ui.getCore().getControl(“e_mail_tf_m”).setValue(response.e_mail);
     sap.ui.getCore().getControl(“country_cb_m”).setValue(response.country);
     sap.ui.getCore().getControl(“city_tf_m”).setValue(response.city);
      });
  
      //userProfileDetailsTable.bindRows(“z_ui5_user_maintCollection(‘”+selectedUserID+”‘)”+”/profiles_r”);
      //userRolesDetailsTable.bindRows(“z_ui5_user_maintCollection(‘”+selectedUserID+”‘)”+”/activitygroups_r”);
      userProfileDetailsTable.bindRows(currentRowContext+”/profiles_r”);
      userRolesDetailsTable.bindRows(currentRowContext+”/activitygroups_r”);     
     });

     userDetailsTable.bindRows(“z_ui5_user_maintCollection”);
     var userDetailsTableLayout = new sap.ui.commons.layout.MatrixLayout();
     userDetailsTableLayout.createRow( userDetailsTable);    
     userDetailsTableLayout.placeAt(“UserDetailsTable”);  
    
     //////////////////////More User Details Tab
var moreUserDetailsLayout = new sap.ui.commons.layout.MatrixLayout();
moreUserDetailsLayout.setLayoutFixed(false);

var titleCombox1 = new sap.ui.commons.ComboBox(“title_cb_m”,{editable : false, maxLength : 3, width:”75px”, value:”{title}”,items:[
                           new sap.ui.core.ListItem({text:”Mr.”}),
                           new sap.ui.core.ListItem({text:”Mrs.”}),
                           new sap.ui.core.ListItem({text:”Ms.”})]}) ;                                                             
    moreUserDetailsLayout.createRow(new sap.ui.commons.Label({text:”Title”, width:”100px”}),titleCombox1);
                             
moreUserDetailsLayout.createRow(
       new sap.ui.commons.Label({text:”First Name”, width:”100px”}),
       new sap.ui.commons.TextField(“firstname_tf_m”,{editable:false, width:”150px”, value : “{firstname}”, required : true}),
       new sap.ui.commons.Label({text:”Last Name”, width:”100px”}),
       new sap.ui.commons.TextField(“lastname_tf_m”,{editable:false, width:”150px”, value : “{lastname}”, required : true}));
moreUserDetailsLayout.createRow(
       new sap.ui.commons.Label({text:”Language”, width:”100px”}),    new sap.ui.commons.TextField(“language_tf_m”,{editable:false, width:”150px”, value : “{language}”}),
       new sap.ui.commons.Label({text:”Department”, width:”100px”}), new sap.ui.commons.TextField(“department_tf_m”,{editable:false, width:”150px”, value : “{department}”}));
moreUserDetailsLayout.createRow(
       new sap.ui.commons.Label({text:”Telephone”, width:”100px”}),
       new sap.ui.commons.TextField(“telephone_tf_m”,{editable:false, width:”150px”, value : “{telephone}”}), new sap.ui.commons.Label({text:”Email”, width:”100px”}),
       new sap.ui.commons.TextField(“e_mail_tf_m”,{editable:false, width:”250px”, value : “{e_mail}”}));

var countryCombox1 = new sap.ui.commons.ComboBox(“country_cb_m”, {editable:false, maxLength : 3, width:”75px”, value:”{country}”,items:[
                            new sap.ui.core.ListItem({text:”US”}),
                            new sap.ui.core.ListItem({text:”IN”}),
                            new sap.ui.core.ListItem({text:”CA”}),
                            new sap.ui.core.ListItem({text:”JP”}),
                            new sap.ui.core.ListItem({text:”UK”}) ]}) ;

   moreUserDetailsLayout.createRow(
   new sap.ui.commons.Label({text:”City”, width:”100px”}),
   new sap.ui.commons.TextField(“city_tf_m”,{editable:false, width:”150px”, value : “{city}”}),
   new sap.ui.commons.Label({text:”Country”, width:”100px”}),countryCombox1);

     var userProfileDetailsTable = new sap.ui.table.DataTable({
   title : “Profiles”,    width : “100%”,    visibleRowCount : 5,    ExpandedVisibleRowCount : 10,    selectionMode : sap.ui.table.SelectionMode.Single,
   editable : false
  });
 
     userProfileDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: “Profile”}),  template: new sap.ui.commons.TextField().bindProperty(“value”, “profile”),
        sortProperty: “profile” }));
      
     userProfileDetailsTable.addColumn(new sap.ui.table.Column({
       label: new sap.ui.commons.Label({text: “Type”}),  template: new sap.ui.commons.TextField().bindProperty(“value”, “type”),
       sortProperty: “type” }));

     userProfileDetailsTable.addColumn(new sap.ui.table.Column({
       label: new sap.ui.commons.Label({text: “Version”}),   template: new sap.ui.commons.TextField().bindProperty(“value”, “version”),
       sortProperty: “version” }));
      
     userProfileDetailsTable.addColumn(new sap.ui.table.Column({  label: new sap.ui.commons.Label({text: “Description”}),
        template: new sap.ui.commons.TextField().bindProperty(“value”, “text”),  sortProperty: “language” }));

     var userRolesDetailsTable = new sap.ui.table.DataTable({
   title : “Roles”,    width : “100%”,   visibleRowCount : 5,   ExpandedVisibleRowCount : 10,   selectionMode : sap.ui.table.SelectionMode.Single,
   editable : false  });
 
     userRolesDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: “Role Name”}),
        template: new sap.ui.commons.TextField().bindProperty(“value”, “role_name”),
        sortProperty: “role_name” }));
      
     userRolesDetailsTable.addColumn(new sap.ui.table.Column({
       label: new sap.ui.commons.Label({text: “Role Id”}),
       template: new sap.ui.commons.TextField().bindProperty(“value”, “role”),        sortProperty: “role” }));

     userRolesDetailsTable.addColumn(new sap.ui.table.Column({
       label: new sap.ui.commons.Label({text: “Valid From”}),       template: new sap.ui.commons.TextField().bindProperty(“value”, “from_dat”),
       sortProperty: “from_dat” }));
      
     userRolesDetailsTable.addColumn(new sap.ui.table.Column({
        label: new sap.ui.commons.Label({text: “Valid To”}),
        template: new sap.ui.commons.TextField().bindProperty(“value”, “to_dat”),
        sortProperty: “to_dat” }));
     //
      var userTab  = new sap.ui.commons.Tab().setText(“Person”).addContent(moreUserDetailsLayout);
      var profilesTab = new sap.ui.commons.Tab().setText(“Profiles”).addContent(userProfileDetailsTable);
      var rolesTab  = new sap.ui.commons.Tab().setText(“Roles”).addContent(userRolesDetailsTable);

      var tabStrip =  new sap.ui.commons.TabStrip({width:”75%”}).addTab(userTab).addTab(rolesTab).addTab(profilesTab);        
      userDetailsTableLayout.createRow(tabStrip);  
–>
</script>

</head>

<body class=”sapUiBody” role=”application”>

<div id=”appBody”></div>

<div id=”UserDetailsTable”></div>
<div id=”UserTabs”></div>
<p></p>
</body>
</html></html>

Second part of this blog is available here.  The second part explains about Create and Delete functionality with corresponding REST operations.

13 Comments
You must be Logged on to comment or reply to a post.
  • Nice blog..couple of questions

    1) Where did you host the Ui5 application? On a local Tomcat server?

    2) How did you overcome the Same Origin Policy while communicating to the Gateway server?

    I am creating a sample app which communicates with the SAP Demo Gateway services, Ui5 app is hosted on a local Tomcat..Cant seem to get away from SOP..Gives access is denied error.

    Thanks

    Sandip

      • Hi Abhilash

        Thanks for a nice post.

        I just wanted to follow up on the 1) and 2) statements you made there: you're using a Tomcat server, presumably listening on one port (say, 8001), and also, on the same host, the Gateway server, presumably listening on another port (say, 8002). As far as I understand the definition of 'origin', the port number is included in the definition, i.e. if the port numbers are different then it's not the same origin, and the same origin policy kicks in.

        So in your case you're still having to use the --disable-web-security feature of Chrome, is that correct?

        cheers

        dj

        • Hi Adams,

          My Tomcat server is running on 8080 and GW server is on 8000 port. As you said though they are in same domain, the port also matters.

          And to run this application on chrome I used --disable-web-security option.

          Thanks

          Abhilash

  • hi Gampa, when I developed OData service in SAP Gateway based on doc

    'How To... Create a Gateway Service Using the RFC Generator - Advanced Scenario' ,

    I encountered a issue in step 4.5.2 Configure a System Alias for the Service. the system alert an error:

    Entry A Z_USER_RFC_XXX  does not exist in /IWFND/I_MED_SRH (check entry)

    Message no. 00058

    Diagnosis

    Input values must be defined in Table /IWFND/I_MED_SRH. The value or values
    'A Z_USER_RFC_XXX ' are not specified in this table.

    But I have created the data model Z_USER_RFC_XXX already, would you pls tell me how to solve this?  thanks.

    • Hi,

      The URL is correct. I just tried the same and I am able to login to GW server with the same credentials mentioned above. When you are using this URL in OData Model you can pass the user/pwd details in ODataModel class as below.

      var oModel = new sap.ui.model.odata.ODataModel( 

                                    "http://gw.esworkplace.sap.com/sap/opu/odata/sap/SALESORDERS/SOHeaders", 

                                                        false, 

                                                        "GW@ESW", 

                                                        "ESW4GW"); 

  • Hi Guys,

    I am creating a SAPUI5 mobile application. I am getting data from Gateway OData Service. On my login page I am using the Gateway username and password to login to the application. But the problem is that call to Gateway OData Service is using user credentials from history so even if the username and password from the login page are wrong still one can login. can some one tell me the solution to this problem.

    Thanks and best regards.

    fahad