
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.
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
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)
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
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).
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).
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.
The table control will be created inside the “createContent” method of the main view.
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.
Executing the application at this point we should see a screen like the one illustrated in the figure below.
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.
Right click the BSP Application name and select the menu option Create -> Page.
Provide a short description. Save and activate it.
Delete the auto-generated code. Copy the index.html code from Eclipse and paste in the BSP page. Save and activate it.
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.
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”.
Refresh the BSP Application structure again. The final structure should be like the one illustrated in the figure below.
Now we need to do the same with the SAPUI5 framework. Its very similar to the steps described above.
We need to:
The final structure should be like the one illustrated in the figure below.
The final step before executing the first test of the ZSCNBLOG2 BSP Application is to adjust the path of the SAPUI5.
Now we can test our application. Open the Developer tools to check if all files were downloaded correctly.
Now we are ready to start the implementation of the controller’s methods.
Open the main.controller.js file in the Eclipse and implement the code below.
/**
* 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() {
}
});
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.
Import the file again.
Go to the browser and refresh the page. Hit the “Create” button. Fill in all fields. Hit the “OK” button.
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.
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.
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.
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.
Well, that's it.
Your feedback is most welcome!
Christian Jianelli
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
6 | |
5 | |
5 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 |