Skip to Content
Author's profile photo Christian Jianelli

Building a CRUD Application with SAPUI5 and ICF REST/JSON Service – Part 3

This is the part 3 of 3 of this blog series. In this part we will see the creation of the user interface using SAPUI5.

Click here if you did not read the Part 2.

Table of Contents

Part 1


Prerequisites

Overview

SAPLink Nuggets and Eclipse Project download

References

SAPUI5

SAPLink

SAPLink plugins (SCN Code Exchange)

CL_TREX_JSON_SERIALIZER bug fixes

Extending SAPUI5 JSON Model

Creating the ICF REST Service

Creating the custom handler class

Creating the ICF node

Retrieving the request method and the parameters passed in the URL

Part 2

Implementing the REST Service

Model and DDIC objects

Implementing the Create method (POST HTTP verb)

Implementing the Read method (HTTP GET verb)

Implementing the Update method (PUT HTTP verb)

Implementing the Delete method (DELETE HTTP verb)

Part 3

Creating the User Interface

Creating the project

Setting up the SAPUI5 bootstrap and required libraries

Creating the view components

Creating the BSPs to deploy the application and the SAPUI5 framework.

Implementing the Controller’s methods

Create

Read

Update

Delete

Find

Creating the project

There is already a very good document published on SCN by Silke Arians that explains how to create a SAPUI5 MVC project from scratch by using the SAPUI5 Application Development Tool.

How to build a SAP HTML5 application using MVC with the SAPUI5 Application Development Tool

http://scn.sap.com/docs/DOC-29890

Here we will skip the basic steps of creating a project and jump direct to the creation of the view components.

Our project will be called “scnblog2” and the view will be called “main”. The view will be created using Javascript (Development Paradigm).

scnblog2_033.JPG

Setting up the SAPUI5 bootstrap and required libraries

Inform the correct path of the “sap.ui.core.js” file in your server and add the required libraries “sap.ui.core” and “sap.ui.table” (see figure below).

scnblog2_035.JPG

Creating the view components

The application will be composed by only one view and this view will be composed by a Table control with five buttons in its toolbar. Its final look is illustrated in the figure below.


scnblog2_032.JPG

The table control will be created inside the “createContent” method of the main view.

scnblog2_034.JPG

Below is the code to create the table control and its toolbar.

         // Creating the table control

         var oTable = new sap.ui.table.Table(“tblctrl”, {

                      title: “CRUD Application Example”,

                      visibleRowCount: 10,

                      firstVisibleRow: 0,

                      selectionMode: sap.ui.table.SelectionMode.Single,

                      toolbar: new sap.ui.commons.Toolbar({

                                 items: [

                                      new sap.ui.commons.Button({

                                                text: “Create”,

                                                press: function() {

                                                     oController.Create();

                                                }

                                      }),

                                          

                                      new sap.ui.commons.Button({

                                                text: “Read (All)”,

                                                press: function() {

                                                     oController.Read();

                                                }

                                      }),

                                          

                                      new sap.ui.commons.Button({

                                                text: “Update”,

                                                press: function() {

                                                     oController.Update();

                                                }

                                      }),

                                          

                                      new sap.ui.commons.Button({

                                                text: “Delete”,

                                                press: function() {

                                                     oController.Delete();

                                                }

                                      }),

                                          

                                      new sap.ui.commons.Button({

                                                text: “Find”,

                                                press: function() {

                                                     oController.Find();

                                                }

                                      })]

                       })

         });

  // Adding the table columns

  // Column E-mail

  oTable.addColumn(new sap.ui.table.Column({

        label: new sap.ui.commons.Label({text: “Email”}),

        template: new sap.ui.commons.Label().bindProperty(“text”, “email”),

        sortProperty: “email”,

        filterProperty: “email”,

        width: “50%”

  }));

 

  // Column Last Name

  oTable.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”,

        filterProperty: “lastname”,

        width: “25%”

  }));

 

  // Column First Name

  oTable.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”,

        filterProperty: “firstname”,

        width: “25%”

  }));

         // Creating the JSON Model – be aware that myJSONModel is an extended (custom)

         // version of the sap.ui.model.json.JSONModel

         var oModel = new myJSONModel;

               

         // Defining our model as global

         sap.ui.getCore().setModel(oModel);

               

         // Data Binding – here we are binding the table control

         // to the “data” attribute of the JSON Model

         oTable.bindRows(“/data”);

               

         // Returning the control(s) to place in the view     

         return [oTable];


Each button have the “press” event handler implemented by an anonymous function that calls the respective method of the controller ( oController.Create(), for example). At this point the controller’s methods are not implemented yet.

We are using an extended (custom) version of the sap.ui.model.json.JSONModel (check the References). The myJSONModel.js file  is avaliable at https://gist.github.com/4218856. To use it in our project We need to create a new folder named “js” and create the myJSONModel.js file inside this folder. We need also to include a new <script> tag in the index.html file. See figures below.

scnblog2_036.JPG

scnblog2_037.JPG

Executing the application at this point  we should see a screen like the one illustrated in the figure below.

scnblog2_038.JPG


Creating the BSPs to deploy the application and the SAPUI5 framework.

Before implement the controller’s methods we need to upload our application and the SAPUI5 framework into the ABAP Application Server. We must do it because we want to avoid headaches caused by CORS (Cross Origin Resource Sharing) .

Go to SE80 transaction, select BSP Application,inform the name of the BSP Application we want to create (ZSCNBLOG2) and hit the Yes button.

scnblog2_039.JPG


Right click the BSP Application name and select the menu option Create -> Page.

scnblog2_041.JPG

Provide a short description. Save and activate it.

scnblog2_042.JPG

Delete the auto-generated code. Copy the index.html code from Eclipse and paste in the BSP page. Save and activate it.

scnblog2_043.JPG

To import the .js files we will use the report BSP_UPDATE_MIMEREPOS. Provide the path of the BSP Application. Select the WebContent folder and hit the Ok button.

scnblog2_045.JPG

Refresh the BSP Application structure. Select the META-INF and WEB-INF folders and the index.html, right click it and select the menu option “Delete”.

scnblog2_047.JPG

Refresh the BSP Application structure again. The final structure should be like the one illustrated in the figure below.

scnblog2_049.JPG

Now we need to do the same with the SAPUI5 framework. Its very similar to the steps described above.

We need to:

  1. Create a BSP Application named ZSAPUI5
  1. Create an index.html page
  1. Delete the code auto-generated. Copy and paste the index.html code from the SAPUI5 into the index.html of the BSP.
  1. Use the report BSP_UPDATE_MIMEREPOS to import the SAPUI5 files.

The final structure should be like the one illustrated in the figure below.


scnblog2_051.JPG

The final step before executing the first test of the ZSCNBLOG2 BSP Application is to adjust the path of the SAPUI5.

scnblog2_050.JPG

Now we can test our application. Open the Developer tools to check if all files were downloaded correctly.

scnblog2_052.JPG

Now we are ready to start the implementation of the controller’s methods.

Implementing the Controller’s methods

Open the main.controller.js file in the Eclipse and implement the code below.

scnblog2_053.JPG

/**

* Called when the Controller is destroyed. Use this one to free resources and finalize activities.

*/

//   onExit: function() {

//

//   }

 

          Create: function() {

 

          },

 

          Read : function() {

 

          },

 

          Update : function() {

 

          },

 

          Delete : function() {

 

          },

 

          Find : function() {

 

          }

});



Create

 

  Below is the code that we need to implement to handle the create method.

  // Create a dialog to get the information of the contact to be created

  var oDialog = new sap.ui.commons.Dialog(“Dialog”, {

          modal: true,

          closed: function(oControlEvent){

                    sap.ui.getCore().getElementById(‘Dialog’).destroy();

          }

  });

 

  oDialog.setTitle(“New Contact”);

 

  // Create a layout to place the controls in the dialog

  var oLayout = new sap.ui.commons.layout.MatrixLayout({

          columns: 2,

          width: “100%”

  });

 

  // Create text field for the e-mail

  var oTF = new sap.ui.commons.TextField(“tfEmail”, {

          tooltip: ‘E-mail’,

          editable: true,

          width: ‘200px’

  });

 

  // Label for the e-mail field

  var oLabel = new sap.ui.commons.Label(“lbEmail”, {

          text: ‘E-mail’,

          labelFor: oTF

  });

 

  // Create the first row

  oLayout.createRow(oLabel, oTF);

          

  // Repeat the same for the fields Last Name and First Name

  // Create text field for the last name

  oTF = new sap.ui.commons.TextField(“tfLastName”, {

          tooltip: ‘Last Name’,

          editable: true,

          width: ‘200px’

  });

 

  // Label for the last name field

  oLabel = new sap.ui.commons.Label(“lbLastName”, {

          text: ‘Last Name’,

          labelFor: oTF

  });

 

  // Create the second row

  oLayout.createRow(oLabel, oTF);

 

  // Create text field for the e-mail

  oTF = new sap.ui.commons.TextField(“tfFirstName”, {

          tooltip: ‘First Name’,

          editable: true,

          width: ‘200px’

  });

 

  // Label for the e-mail field

  oLabel = new sap.ui.commons.Label(“lbFirstName”, {

          text: ‘First Name’,

          labelFor: oTF

  });

 

  // Create the third row

  oLayout.createRow(oLabel, oTF);

 

  // Add the layout to the dialog

  oDialog.addContent(oLayout);

 

  // Add a button to post the contact’s data to the REST interface

  oDialog.addButton(new sap.ui.commons.Button({text: “OK”, press:function(){ 

 

     var oModel2 = new myJSONModel;

 

    // Retrieve the contact information from the text fields

     var oParameters = {

           “email” : sap.ui.getCore().getElementById(‘tfEmail’).getValue(),

           “lastname” : sap.ui.getCore().getElementById(‘tfLastName’).getValue(),

           “firstname” : sap.ui.getCore().getElementById(‘tfFirstName’).getValue()

     };

 

     // Post data to the REST interface

     oModel2.loadDataNew(“../../../zscnblog2/contact/”, handleSuccess, handleError,     oParameters, true, ‘POST’);

 

     function handleSuccess(oData){

  

           if(oData.success===’true’){

            

              // Retrieve the data from the global model

              var oData2 = sap.ui.getCore().getModel().getData();

                      

              // If the global model has already any data then the models are merged

              // If not, then the global model is populated with the new contact

           if(jQuery.isArray(oData2.data)){

                      oData2.data = jQuery.merge(oData2.data, oData.data);

               }else{

                      oData2.data = jQuery.merge([], oData.data);

            }

                      

               // Refresh the Global Model Data

               sap.ui.getCore().getModel().setData(oData2, false);

            

          }

            

          // Close the Dialog

          sap.ui.getCore().getElementById(‘Dialog’).close();

            

          // Display message

          sap.ui.commons.MessageBox.alert(oData.msg);

  

   }

 

   function handleError(){

          // Display message

          sap.ui.commons.MessageBox.alert(arguments[0].statusText);

   }

 

  }}));

 

  Dialog.open();

 

},

Now let’s test. Open the BSP Application ZSCNBLOG2 and delete the main.controller.js file.


scnblog2_054.JPG


Import the file again.


scnblog2_055.JPG

Go to the browser and refresh the page. Hit the “Create” button. Fill in all fields. Hit the “OK” button.

scnblog2_056.JPG

scnblog2_057.JPG

Read

Below is the code that we need to implement to handle the read method.

  // Retrieve the Global Model

   var oModel = sap.ui.getCore().getModel();

  

  // Send the GET request

   oModel.loadDataNew(“../../../zscnblog2/contact/”, handleSuccess, handleError );

  

   function handleSuccess(oData){

  

          if(oData.success===’false’){

              // Display message

              sap.ui.commons.MessageBox.alert(oData.msg);

          }

            

   }

 

   function handleError(){

          // Display message

          sap.ui.commons.MessageBox.alert(arguments[0].statusText);

   }

Let’s test it. Repeat the steps of deleting and importing the main.controller.js. Go to the browser and refresh the page. Hit the “Read (All)” button.

scnblog2_059.JPG

Update

Below is the code that we need to implement to handle the Updatemethod.

var oModel = new myJSONModel;

 

       // Get a reference of the table control

       var oTable = sap.ui.getCore().getElementById(‘tblctrl’);

 

       // Retrieve the selected index, i.e., the index of the selected row

       var i = oTable.getSelectedIndex();

 

       // Base URL of the REST service

       var ServiceURL = “../../../zscnblog2/contact/”;

 

      if(i>=0){

 

           // Retrieve the selected row

           var selectedRow = oTable.getRows()[i];

 

           // Concatenate the Base URL and the contact’s e-mail

           // Example: “../../../zscnblog2/contact/christianjianelli@gmail.com

           ServiceURL = ServiceURL + selectedRow.getCells()[0].getText();

 

           // The parameters that will be sent to the server as form fields

           var oParameters = {

                “email” : selectedRow.getCells()[0].getText(),

                “lastname” : selectedRow.getCells()[1].getValue(),

                “firstname” : selectedRow.getCells()[2].getValue()

           };

 

           // Send PUT request

           oModel.loadDataNew(ServiceURL, handleSuccess, handleError, oParameters, true, ‘PUT’);

 

      }else{

           // User have not selected any row

           sap.ui.commons.MessageBox.alert(‘No record selected’);

      }

 

      function handleSuccess(oData){

           // Display message

           sap.ui.commons.MessageBox.alert(oData.msg);

      }

 

      function handleError(){

           // Display message

           sap.ui.commons.MessageBox.alert(arguments[0].statusText);

      }

Let’s test it. Repeat the steps of deleting and importing the main.controller.js. Go to the browser and refresh the page. Hit the “Read (All)” button, change the last and first names, select the row and hit the “Update” button.

scnblog2_061.JPG

Delete

Below is the code that we need to implement to handle the Delete method.

var oModel = new myJSONModel;

 

       // Get a reference of the table control

       var oTable = sap.ui.getCore().getElementById(‘tblctrl’);

 

       // Retrieve the selected row

       var selIndex = oTable.getSelectedIndex();

 

       // Base URL of the REST service

       var ServiceURL = “../../../zscnblog2/contact/”;

 

       var oParameters = {};

 

       if(selIndex >= 0){

 

         // Retrieve the selected row

         var selectedRow = oTable.getRows()[selIndex];

 

         // Concatenate the Base URL and the contact’s e-mail

         // Example: “../../../zscnblog2/contact/christianjianelli@gmail.com

         ServiceURL = ServiceURL + selectedRow.getCells()[0].getText();

 

         // Send DELETE request

         oModel.loadDataNew(ServiceURL, handleSuccess, handleError, oParameters, true, ‘DELETE’);

 

       }else{

         // User have not selected any row

         sap.ui.commons.MessageBox.alert(‘No record selected’);

       }

       function handleSuccess(oData){

 

            if(oData.success===’true’){

 

               // Retrieve the selected row

               var selectedRow = oTable.getRows()[selIndex];

 

               // Retrieve the Global Model

               var oData2 = sap.ui.getCore().getModel().getData();

 

                    if(jQuery.isArray(oData2.data)){

 

                          // Remove the deleted contact from the Global Model data

                          oData2.data = jQuery.grep(oData2.data, function(n,i){

                               return n.email !== selectedRow.getCells()[0].getText();

                          });

 

                          // Update the Global Model data

                          sap.ui.getCore().getModel().setData(oData2, false);

                     }

            }

 

            // Display message  

            sap.ui.commons.MessageBox.alert(oData.msg);

       }

 

       function handleError(){

            // Display message

            sap.ui.commons.MessageBox.alert(arguments[0].statusText);

       }

Let’s test it. Repeat the steps of deleting and importing the main.controller.js. Go to the browser and refresh the page. Hit the “Read (All)” button, select the row and hit the “Delete” button.

http://www.jianelli.com.br/sap/scnblog2/scnblog2_064.JPG

Find

In fact, this method is the read method, but once our read method returns always all records, it is worthwhile to see how can we search for specific contact.

Below is the code that we need to implement to handle the Find method.

   // Create a dialog to get the information of the contact(s) to find

          var oDialog = new sap.ui.commons.Dialog(“Dialog”, {

                    modal: true,

                    closed: function(oControlEvent){

                              sap.ui.getCore().getElementById(‘Dialog’).destroy();

                    }

          });

 

          oDialog.setTitle(“Find Contact”);

 

          // Create a layout to place the controls in the dialog

          var oLayout = new sap.ui.commons.layout.MatrixLayout({

                    columns: 2,

                    width: “100%”

          });

 

          // Create text field for the e-mail

          var oTF = new sap.ui.commons.TextField(“tfEmail”, {

                    tooltip: ‘E-mail’,

                    editable: true,

                    width: ‘200px’

          });

 

          // Label for the e-mail field

          var oLabel = new sap.ui.commons.Label(“lbEmail”, {

                    text: ‘E-mail’,

                    labelFor: oTF

          });

 

          // Create the first row

          oLayout.createRow(oLabel, oTF);

 

          // Repeat the same for the fields Last Name and First Name

  

          // Create text field for the last name

          oTF = new sap.ui.commons.TextField(“tfLastName”, {

                    tooltip: ‘Last Name’,

                    editable: true,

                    width: ‘200px’

          });

   // Label for the last name field

          oLabel = new sap.ui.commons.Label(“lbLastName”, {

                    text: ‘Last Name’,

                    labelFor: oTF

          });

 

          // Create the second row

          oLayout.createRow(oLabel, oTF);

 

          // Create text field for the e-mail

          oTF = new sap.ui.commons.TextField(“tfFirstName”, {

                    tooltip: ‘First Name’,

                    editable: true,

                    width: ‘200px’

          });

 

          // Label for the e-mail field

          oLabel = new sap.ui.commons.Label(“lbFirstName”, {

                    text: ‘First Name’,

                    labelFor: oTF

          });

 

          // Create the third row

          oLayout.createRow(oLabel, oTF);

 

          // Add the layout to the dialog

          oFirstDialog.addContent(oLayout);

       

          // Add a button to post the contact’s data to the REST interface

          oFirstDialog.addButton(new sap.ui.commons.Button({text: “OK”, press:function(){

 

                    // Get a reference of the Global Model

                    var oModel = sap.ui.getCore().getModel();

 

                    // The parameters that will be sent to the server

                    // as query string in the URL

                    var oParameters = {

                       “lastname” : sap.ui.getCore().getElementById(‘tfLastName’).getValue(),

                       “firstname” : sap.ui.getCore().getElementById(‘tfFirstName’).getValue()

                    };

 

                    // Base URL of the REST service

                    var ServiceURL = “../../../zscnblog2/contact/”;

                 

                    // Concatenate the Base URL and the contact’s e-mail

                    // Example: “../../../zscnblog2/contact/christianjianelli@gmail.com

                    ServiceURL = ServiceURL + sap.ui.getCore().getElementById(‘tfEmail’).getValue();

 

                    // Send the request

                    oModel.loadDataNew(ServiceURL, handleSuccess, handleError, oParameters);

     

      function handleSuccess(oData){

            

                        if(oData.success===’false’){

                          // Display message

                           sap.ui.commons.MessageBox.alert(oData.msg);

                        }else{

                           // Close the dialog

                           sap.ui.getCore().getElementById(‘Dialog’).close();  

                        }

            

                    }

 

                    function handleError(){

                              // Display message

                              sap.ui.commons.MessageBox.alert(arguments[0].statusText);

                    }

 

          }}));

 

          oFirstDialog.open();

Let’s test it. Repeat the steps of deleting and importing the main.controller.js. Go to the browser and refresh the page. Create two new contacts. Refresh the page again. Hit the “Find” button, choose one of the 3 fields to find the contact and hit the “OK” button.


http://www.jianelli.com.br/sap/scnblog2/scnblog2_065.JPG

http://www.jianelli.com.br/sap/scnblog2/scnblog2_066.JPG

Well, that’s it.

Your feedback is most welcome!

Christian Jianelli



Assigned Tags

      65 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Silke Arians
      Silke Arians

      Short remark:

      If you have the SAP NetWeaver AS ABAP 7.31 with the UI Add-On, we provide a UI5 Repository based on the BSP Repository and an Eclipse-based SAPUI5 ABAP Team Provider tool to deploy it on the ABAP server.

      For more information see

      Best regards

      Silke

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Silke,

      In fact, what I wanted to show here is that is possible to try SAPUI5 even without these tools. Of course, these tools will make our life easier. 🙂

      Thanks for your feedback.

      Best regards

      Christian

      Author's profile photo Former Member
      Former Member

      Hi silke,

      how some can deploy a third-party script with the abap team provider? for me it does not work?!

      BR,

      Alex

      Author's profile photo Mingzuo Shen
      Mingzuo Shen

      Thanks very much for the 3-part series!

      Question:

      How to show all the rows when the page is first loaded?

      I see "No data".

      Only when I click on the 'Read (All)' button, then all the expected rows are shown.

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Mingzuo,

      You can use the onInit method of the Controller to call the Read method.

        onInit: function() {

                   this.Read();

        },

      Thanks for your feedback

      Regards,

      Christian

      Author's profile photo Mingzuo Shen
      Mingzuo Shen

      Thanks so much Christian!

      That worked! Rocking...

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      😉

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Shahid,

      Thanks for your comments. 🙂

      About charts, please check the sap.viz.ui5 documentation at https://sapui5.netweaver.ondemand.com/sdk/#docs/api/symbols/sap.viz.ui5.html

      Be aware that it is an experimental API yet.

      Regards,

      Christian

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Shahid,

      You can try DOM insertion using JQuery selector and manipulation.

      Please try the code below using the chrome developer tools in the Shell Example.

      $('#myButton').after('<input type="text" x-webkit-speech="x-webkit-speech" />');

      Shell Example link

      https://sapui5.netweaver.ondemand.com/sdk/content/Controls/UX3Controls/ShellExample.html

      Ps: navigate to Examples -> Button to test the code.

      Regards,

      Christian


      Author's profile photo Former Member
      Former Member

      I can't see the captured images. Just in my case?

      Regards,

      JHYang.

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      It seems that the images were deleted for some reason. I will upload again soon.

      Thanks,

      Christian

      Author's profile photo Silke Arians
      Silke Arians

      Hello Abdul Raheem,

      As an alternative for SAP Business Suite system of version 7.00 and higher - especially until 7.31 - you may use the interactive ABAP report /UI5/UI5_REPOSITORY_LOAD

      offering similiar functionality. Compared to the Team Repository

      Provider it does not offer a built-in code merge. Here an separate

      source code repository like git, Suberversion (SVN) etc. may be used.

      The report is shipped via SAP note 1793771 "Up/Download SAPUI5

      Application into/from UI5 Repository" and within SP03 of the NetWeaver

      UI Add-On. Find the corresponding documentation in the note and attached

      to the report.

      Kind regards

      Silke

      Author's profile photo Former Member
      Former Member

      Hi,

      Thank you very much for the quick reply Since I found the answer earlier  I deleted the question.

      Author's profile photo Former Member
      Former Member

      Hi Christian,

      Thanks for such a wondeful blog, helped a lot.

      With your tutorial, i reached till end, now when i m working on my project I am getting the following error which I am not able to resolve:

      Uncaught TypeError: Object #<Object> has no method 'toUpperCase'

      This is coming, when I am CREATING data in SAP backend using POST action. Code for the same is:

      // Retrieve the  information from the text fields

                                                                  var oParameters = {

                                                                            "name" : sap.ui.getCore().getElementById('name').getValue(),

                                                                            "pdesc" : sap.ui.getCore().getElementById('pdesc').getValue(),

                                                                  };

       

                                                                  // Post data to the REST interface

                                                                  oModel2.loadData("http://****:8000/sap/bc/zdservice?sap-client=***",

                                                                                      handleSuccess, handleError, oParameters,true,'POST');

      Will be glad if you could help..

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Dav,

      Thanks for your feedback 🙂

      I believe the error you are getting is because you are not using the correct JSONModel. In my blog I used an extended (custom) version of the JSONModel.

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hello Christian,

      Thanks for the blog. I am able to replicate the example but I get an error at the end when trying to get data. I am trying the scenario for find a customer by email. and I get the below errors in IE8.

      The following problem occurred: parsererror - {success: "true", msg: "", data: [{email:.................}], 200,ok

      Below is another error on load of page and I am seeing this in Chrome. I am wondering if the sap.ui.core.js is not initialized properly.

      Failed to load resource: the server responded with a status of 404 ((BSP) Error)             

      x.extend.ajax          sap-ui-core.js:25

      a                            sap-ui-core.js:69

      d                             sap-ui-core.js:69

      properties                 sap-ui-core.js:69

      l                               sap-ui-core.js:69

      B                              sap-ui-core.js:69

      a                               sap-ui-core.js:69

      sap.ui.core.Core.getLibraryResourceBundle             sap-ui-core.js:69

      (anonymous function)                                             sap-ui-core.js:69

      sap.ui.table.Table.init                                             Table.js:7

      sap.ui.base.EventProvider.extend.constructor          sap-ui-core.js:69

      sap.ui.core.Element.extend.constructor                  sap-ui-core.js:69

      f                                                                          sap-ui-core.js:69

      b                                                                         sap-ui-core.js:69

      sap.ui.jsview.createContent                                   myview.view.js:9

      (anonymous function)                                            JSView.js:6

      sap.ui.core.Element.runWithPreprocessors                             sap-ui-core.js:69

      sap.ui.core.mvc.JSView.onControllerConnected                       JSView.js:6

      sap.ui.core.mvc.View._initCompositeSupport                           View.js:6

      sap.ui.base.EventProvider.extend.constructor                          sap-ui-core.js:69

      sap.ui.core.Element.extend.constructor                                  sap-ui-core.js:69

      f                                                                                          sap-ui-core.js:69

      f                                                                    sap-ui-core.js:69

      b                                                                   sap-ui-core.js:69

      sap.ui.view                                                     View.js:6

      b.(anonymous function)                                   sap-ui-core.js:69

      (anonymous function)

      The source on the index.html file is declared as

      src="................/ZSAPUI5/resources/sap-ui-core.js"

      I was wondering if the BSP error is causing the parsing error in JSON.

      I am able to display the layout of the table which tells that the UI 5 librabry is loading but then I get the error when I am searching.

      Thanks!

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Arvind, thanks for your feedback!

      I believe that you left behind the last prerequisite

      Your JSON is invalid. It should be

      {"success": "true", "msg": "", data: [{"email":.................}]

      with double quotes around the names

      Hope it helps.

      Best regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Thanks ! that resolved the issue. This is wonderful !

      Author's profile photo Frank Henrdz
      Frank Henrdz

       

      Hi Christian  ,   i'm just currently developing your Demo , but when i click in your link 'with the necessary bug fixes' the page is not active , where can i see the changes to do to the Z json class copy ?       Regards Frank

      Author's profile photo Former Member
      Former Member

      HI Christian,

      Thanks for such nice Blog...

      And valuble help.. 🙂 ...my demo is working fine.1+

      Regards,

      Praphull

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Praphull,

      It's great to see that the blog is helpfull. Thanks for your feedback!

      Best regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi Christian

      Have you experimented this way of interfacing with SAP on Mobile Devices

      I developed an application focused for Mobile devices and in my "HANDLE_REQUEST" method I handle a few different "verbs" I have "GET"  "NEW" and  "SEND". I then tested on different devices.

      Apple: These devices works the best with UI5

      Android: The application works 100% but loads funny sometimes

      My problem however is currently as follows

      For Blackberry devices it seem the "VERB" is always "GET" when it reaches SAP. Have you or anyone else experienced the same issue? Is there something different i need to do in the JSON model?

      Thanks for your help

      Christiaan

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Christiaan,

      Why are you using these verbs? To be honest I never saw the use of "NEW" and "SEND" verbs. Actually I don't even know if they really exist. I would like to ask you to check the information in the following link:

      http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Thanks Christian

      Although you can use any descriptive name for your HTTP request method, it is not always supported supported. I quote from you link "Any client can use any method and the server can be configured to support any combination of methods."

      In my case BlackBerry does not support it.

      Below is a helpful link if you want to test your browsers capability:

      http://www.mnot.net/javascript/xmlhttprequest/

      Author's profile photo Prabaharan Asokan
      Prabaharan Asokan

      Christian,

      It takes plenty of time to upload the UI5 files to MIME repository. 😕

      Prabaharan

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Prabaharan,

      Yes, there are too many files to upload, especially if you are uploading the demokit.

      Regards,

      Christian

      Author's profile photo Meet Mukeshkumar Vajaria
      Meet Mukeshkumar Vajaria

      Hi Christian Jianelli,

      I am having a problem in the last step. I implemented Create: function() in main.controller.js. When I click the button, there is no response. It does not open dialog box. The same happens for find button.

      When I click read, update or delete, it shows "no raw selected" which is acceptable as there is no record on the display.

      From BSP Application, there is no response of any button. I created a sample button on index.html. Even that button is not being displayed.

      Even In Postman-chrome, I am not able to see data when I call any method. But When I call "Post", data is being uploaded in table. So method are supposed to be working. But display is not proper.

      Can you please tell me where did i make mistake?

      Waiting for your reply.

      Thank you.

      Meet Vajaria

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Meet,

      Have you tried to debug the application?

      In order to help you I really need detailed information about the error.

      I suggest you to put an external breakpoint in the handle_request method to identify why the service is not returning any data.

      Best regards,

      Christian

      Author's profile photo Meet Mukeshkumar Vajaria
      Meet Mukeshkumar Vajaria

      Ok Christian, I will put breakpoint in handle_request and try to figure out what is wrong.

      Thank you

      Meet Vajaria

      Author's profile photo Holger Stumm
      Holger Stumm

      Hi Christian

      this is such a great blog. I have a lot of customers that are far away from 7.3, but still want to use this technology.

      Super Great!!

      cheers

      Holger

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Holger,

      Thanks for your feedback. I'm glad you liked it 🙂

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi!

      Where can I find SAPUI5 files to create ZSAPUI5 application?

      Regards,

      Mateusz

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Mateusz,

      You can download it from

      http://scn.sap.com/community/developer-center/front-end

      The files that you need are in the file sapui5-static.zip

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      also can download it from http://www.sapui5.org/sapui5blogs/tools-sdk/

      Author's profile photo Frank Henrdz
      Frank Henrdz

       

      Hi Julio,  in wich part of  http://www.sapui5.org/sapui5blogs/tools-sdk/   are located the ui5 files to download ?     Regards   Frank

      Author's profile photo Frank Henrdz
      Frank Henrdz

       

      Hi Christian,  in wich part of the page https://www.sap.com/community/topic/ui5.html

      is the file  sapui5-static.zip  ?

      Regards

      Frank

      Author's profile photo Former Member
      Former Member

      hi!

      greate tutorial!

      but i have on issue:

      i develope with eclipse and the abap team provider toolkit, to submit my project on the server. i do exactly what you wrote ( add a new folder "js" insert the script, which i have downloaded). but after upload, the file /folder has not be uploaded. is there something else to do?

      regards,

      Alex

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Alexander,

      Thanks for your feedback. Sorry for the late reply but i didn't see your question before. I use eclipse for sapui5 developments but i'm not using the abap team provider tool. Do you still have the problem or you already managed to solve it?

      Regards,

      Christian

      Author's profile photo Martin English
      Martin English

      Christian,

      Excellent work. I have used these blogs as the foundation (perhaps even most of) a DemoJam for this year's Melbourne SIT. Now, deploying SAPUI5 on an ABAP server implies (at the very least)

      a) The system has the appropriate levels of other support packs (see note),

      b) A Maintenance Certificate so you can load the UI5 Add-on via he SAINT transaction,

      c) and access to the STACK XML from Solution Manager

      I was able to create the web portion (the presentation layer, for want of a better word) using Eclipse, and deploy it using Apache, all on my laptop, but my challenge is that I am 'resting between engagements', and don't have (legal / licensed) access to a full ABAP system.

      Solving this has the benefit being that someone new to ABAP would also be able to experiment with UI5 with the tools available to a stand-alone developer; I'm talking here about the sort of person who would not only not have access to SAP licenses, but wouldn't even have an S number to access the SAP Market Place, let alone have the network or knowledge to access the UI5 Add-on, let alone install it.

      The short version is that I downloaded OPEN UI, unzipped it to the file system of my NW702 SP06 Developers edition and made the resulting file system available via HTPP by use of the icm/HTTP/file_access_1 profile parameter. I imported my Eclipse project files into my ABAP server via cut-and-paste for the index.html, and BSP_UPDATE_MIMEREPOS for  the JS components and it works perfectly.

      In other words, you can deploy UI5 applications on ;

      1. production landscapes where you can't get access to SAINT (and Solution manager) to import the ABAP runtime components
      2. production landscapes that don't meet the requirements of the SAP UI5 Add-on
      3. and SAP Developer Editions, where you don't get a maintenance certificate.

      There is also the implication that you can use the same technique for legacy systems (4.6 / 4.7); However, I need access to such a system to test that.

      hth

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Martin,

      I'm really glad to see that this blog is being useful for you as much as it was for myself.

      I didn't know about the icm/HTTP/file_access_1 profile parameter. How does it works when you have multiple Web Application Servers?

      Thanks for your feedback.

      Regards,

      Christian

      Author's profile photo Martin English
      Martin English

      two points;

      First, I have only just realised I don't need the icm/HTTP/file_access_1 profile parameter, because I don't need to access the OpenUI5 library on my server. I can ensure I'm using the latest library using

      src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js'

      secondly, icm/HTTP/file_access_1profile parameter with multiple Web Application Servers?

      Say we install two ABAP systems on the same server (call the server martin). They will need different system IDs (lets say N72 and N74). They will also need different system numbers, so lets install N72 as system number 00 and N74 as system number 10.

      Using RZ10, looking at the instance profile (which will be N72_DVEBMGS00_MARTIN and N74_DVEBMGS10_MARTIN depending on which system you are logged on to), we will see that the icm/server_port_0 setting is the default PROT=HTTP,PORT=80$$. The $$ is a placeholder for the system number.

      So to access an ICF service on N72, you go http://martin.<domain-name>.<tld>:8000/sap/bc/bsp/myservice/

      and to access an ICF service on N74, you go http://martin.<domain-name>.<tld>:8010/sap/bc/bsp/myotherservice

      Similar logic applies to the icm/HTTP/file_access_1 profile parameter;

      if you have

      icm/HTTP/file_access_1 = PREFIX=/N72ui5/,DOCROOT=E:\usr\sap\openui5,BROWSEDIR=2,CACHECTRL=0

      in the N72 instance profile and

      icm/HTTP/file_access_1 = PREFIX=/N74ui5/,DOCROOT=E:\usr\sap\openui5,BROWSEDIR=2,CACHECTRL=0

      in the N74 instance profile,

      the following URLS will access the same file system on the server

      http://martin.<domain-name>.<tld>:8000/N72ui5/ and

      http://martin.<domain-name>.<tld>:8010/N74ui5/

      HTH

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Thanks a lot!!

      Author's profile photo Martin English
      Martin English

      See A Simple UI5 application running against ABAP without the SAP UI5 Add for an explanation of how I expanded slightly on Christian's work here to develop an ABAP application using UI5 without installing the UI5 Addon and (ultimately) without installing anything on my server (except via the SAP GUI, which is as it should be 🙂 )

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Martin,

      Excelent blog. Thanks a lot!

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Thanks for the blog Christian 🙂

      Can i suggest for the "Read" method, that the cache be set to false?

      oModel.loadDataNew("../../../zscnblog2/contact/", handleSuccess,handleError,{}, true,'GET',{},false);


      I was having issues getting the latest records after an update/delete/creation operation as the browser still caches the old records.

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Samuel,

      Yes, sure, suggestions are always welcome. I had the same issues 🙂 .

      But instead of passing all these parameters I decided to change the loadDataNew method by setting the default value of the parameter bCache to false.

      if (bCache === undefined) {

        bCache = false;

      }

      Thanks for your feedback!

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi Christian.

      Thanks for good contribution!.

      I tested your sample. But I can't consume the REST service directly:

      Old.


      oModel.loadDataNew("../../../zscnblog2/contact/", handleSuccess, handleError );

      New.

      oModel.loadDataNew("http://miserver:port/sap/bc/zscnblog2?sap-client=800", handleSuccess, handleError );


      How I can do it? Please Help me.

      Regards,

      Roger

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Roger, thanks for your feedback!

      Sorry, but I didn't get what is wrong. Please provide more information about the error. You can get it using the developer tools of your browser. It can be a CORS (Cross-Origin Resource Sharing) issue.

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi Christian.

      I want to use directly the SAP url REST service in my HTML5 application. It means :

      URL = "http://miserver:port/sap/bc/zscnblog2?sap-client=800" (SAP url REST service");

      oModel.loadDataNew(URL, handleSuccess, handleError );


      I hope your help.

      Regards.

      Roger

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Roger,

      Ok, but what I need to know is why you can't do that. The only difference is that you are using an absolute URL while I used a relative URL. The only thing that can prevent you from calling your REST service using the absolute URL is CORS (if your web application is hosted in server that is not the same of the service).

      Author's profile photo Paulo Cesar de Biasi Vantini
      Paulo Cesar de Biasi Vantini

      Hi Christian,

      thanks a lot for all the hard work you´ve done to create these series in a didatic form.

      It really takes a lot of time to upload the ui5 files to the mime repository but it is worth the effort.

      Best regards!

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Paulo,

      Thanks for your feedback.

      Yes, it takes a lot of time but if you have access to the operating system and permission to change the system profile, you can do what Martin English did in his blog to make UI5 available on the server.A Simple UI5 application running against ABAP without the SAP UI5 Add-on

      Best regards,

      Christian

      Author's profile photo Paulo Cesar de Biasi Vantini
      Paulo Cesar de Biasi Vantini

      Christian,

      thanks again for referring to Martin´s tutorial. I do not know much about basis so I have never heard about using profile parameter icm/HTTP/file_access_1. But it is very practical and useful to reuse the ui5 library through the WAS.

      Best Regards.

      Author's profile photo Former Member
      Former Member

      Hi Christian,

      Super blog...I am getting time out error in ICF call. We have change the Keep Alive to 240 and Proc.Timeout to 900 but still we are getting time out error. Please suggest.


      Regards,

      Sid 🙂

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Siddesh, thanks for your feedback!

      Have you tried to access another service or bsp application of your system? Have you tried to put an external breakpoint to make sure that the timeout is not being caused by your code?

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi Christian,

      Front end is dot Net. There is no error log with time out in st22 so please confirm whether time out error will be logged in st22 or not.

      Regards,

      Sid

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Siddesh,

      I believe that ICM timeouts are not logged in ST22. I suggest you to put an external breakpoint for the user that you are using to connect to the service to make sure that the HTTP calls are reaching it.

      Regards,

      Christian

      Author's profile photo Former Member
      Former Member

      Hi christian,

      I already tried, http call is reaching the service but we are getting timeout error before the service is executed completely.

      Regards,

      Sid

      Author's profile photo Christian Jianelli
      Christian Jianelli
      Blog Post Author

      Hi Siddesh,

      Ok, have you tried to increase the timeout on the client side?

      Author's profile photo Former Member
      Former Member

      Hi christian,

      It's working now. We changed the timeout to - 1(infinite ie till we get response ) in front end. Thanks for your support.

      Regards,

      Sid

      Author's profile photo Former Member
      Former Member

      Hi Christian,

      Thanks for such a wondeful blog, helped a lot.

      With your tutorial, i reached till end, now when i m working on my project I am getting the following error which I am not able to resolve:

      Uncaught TypeError: oModel.loadDataNew is not a function

      Author's profile photo Vadim Zaripov
      Vadim Zaripov

      Hi Christian,

      Great blog! Checking it for the second day.

      There seems to be an error in Create function, the Dialog call should be "oDialog.open();" not "Dialog.open();".

      Thanks, Vadim.

      Author's profile photo Manjunath Babu Rayampalli
      Manjunath Babu Rayampalli
      • Hi    basically im trying to upload an image  using post url in UI5, is there any way i can achieve it using UI5 APplication. i am executing below code after clicking button.

           OData.request({

                                                              requestUri : "ServiceURL",

                                                              method : "GET",

                                                              headers : {

                                                              "X-Requested-With" : "XMLHttpRequest",

                                                              "Content-Type" : "application/atom+xml",

                                                              "DataServiceVersion" : "2.0",

                                                              "X-CSRF-Token" : "Fetch"

                                                              }

                                                              },

                                                              function(data, response) {

                                                              header_xcsrf_token = response.headers['x-csrf-token'];

                                                              oHeaders = {

                                                              "x-csrf-token" : header_xcsrf_token,

                                                              'Accept' : 'application/json',

                                                              };

                                                            

                                                               OData.request({

                                                                            requestUri : "<post URL>",

                                                                            method : "POST",

                                                                            headers : oHeaders,

                                                                            data : oEntry

                                                                            },               

                                                                            function(data,request) {

        //                                                                    loadAttachment();

                                                                            },

                                                                            function(err){

                                                                            sap.m.MessageToast.show("Couldn't Deleted due to following exception : "+ err);

                                                                            });

                                                              },

                                                            

                                                              function(err) {

                                                              var request = err.request;

                                                              var response = err.response;

                                                              sap.m.MessageToast.show("Error in Get -- Request " + request + " Response " + response);

                                                              });



        But i am getting error:TypeError: undefined is not an object (evaluating 'sap.AuthProxy.OData.request')


        Appreicated any help here 🙂


        Regards,MBR

      Author's profile photo Former Member
      Former Member

      Hi Christian,
      excellent tutorial, good job.

      A question, erroja me this message when I run the program and pressed the Create button in Chrome:
      Uncaught Error: "true" is of type string, expected boolean for property "modal" of Element sap.ui.commons.Dialog#Dialog

      but en IE 11 run correctty, Why does this happen?

      Author's profile photo Matthias Schmalz
      Matthias Schmalz

      Hi,

      these instructions are really outdated and not recommended. Since years there's a better mechanism for this, e.g. see https://sapui5.hana.ondemand.com/#/topic/a560bd6ed4654fd1b338df065d331872

      Could you please mention this on top?

      Best regards

      Matthias