As we commented in the previous tutorial, we are going to create a CRUD solution using OpenUI5 as front end, MariaDB as back end and OData as gateway.
The first part of this tutorial had focus on environment configuration and the construction of the back end and gateway.
This second part have the creation of OpenUI5 front end project consuming an OData service and implementing CRUD methods. This is a great end to end solution and I hope you enjoy it.
Prerequisites:
Step-by-Step:
SAP SDK and Tomcat Application Server
The first step is download and extract the SDK from SAP Development Tools page (the link is in the prerequisites).
Java Web Tomcat 7 is the required version for this tutorial.
In eclipse IDE, open Windows / Preferences.
In Server / Runtime Environments click on Add.
Select Java Web Tomcat 7 and click on Next.
Browse the folder were was extracted the SDK zip and Finish.
In eclipse IDE, open Windows / Show View / Servers.
Right click on Servers view and select New / Server.
Find in SAP folder Java Web Tomcat 7 Server. The server name is the same that you created previously. Finish.
OpenUI5 Front End
In eclipse IDE, create a new project in Project Explorer / New / Other.
In the folder SAPUI5 Application Development select Application Project and click on Next.
- Set People_OpenUI5 as name.
- Select sap.m as Library.
- Deselect Create an Initial View option.
- Finish.
Replace the code in index.html file with this one. (I’ve added an space that should be removed between “<” and “script or /script”, because if not the browser consider it as an code insertion and changes the example code)
<!DOCTYPE html> <html> <head> <meta http-equiv="cache-control" content="no-cache" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <title>OpenUI5 with OData and MariaDB</title> < script id="sap-ui-bootstrap" src="resources/sap-ui-core.js" data-sap-ui-theme="sap_belize" data-sap-ui-libs="sap.m" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async" data-sap-ui-resourceroots='{"e2e.ui5": "./"}'> < /script> < script> sap.ui.getCore().attachInit(function() { new sap.ui.core.ComponentContainer({ name : "e2e.ui5" }).placeAt("content"); }); < /script> </head> <body class="sapUiBody" id="content"> </body> </html>
In the folder WebContent create a new file named Component.js
Set this code in Component.js file. This join the Component with the manifest.json.
sap.ui.define([ “sap/ui/core/UIComponent” ], function(UIComponent) {
“use strict”;
return UIComponent.extend(“e2e.ui5.Component”, {
metadata : {
manifest : “json”
},
init : function() {
UIComponent.prototype.init.apply(this, arguments);
}
});
});
- In WebContent folder create a new folder named view.
- In view folder create a new file named CRUD.view.xml
Put this code in CRUD.view.xml file.
<mvc:View xmlns=”sap.m” xmlns:mvc=”sap.ui.core.mvc” xmlns:core=”sap.ui.core”
xmlns:l=”sap.ui.layout” xmlns:f=”sap.ui.layout.form” controllerName=”e2e.ui5.controller.CRUD”>
<App>
<pages>
<Page title=”CRUD view with OpenUI5″>
<content>
<IconTabBar id=”idTopLevelIconTabBar”>
<items>
<IconTabFilter id=”Tab1″ text=”{i18n>cContent}” >
<content>
<l:Grid vSpacing=”2″ defaultSpan=”XL12 L12 M12 S12″>
<VBox>
<f:SimpleForm title=”{i18n>formAdd}”>
<Label text = “{i18n>personPhone}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Phone Number”/>
<MaskInput id=”input01″ mask=”9999999999″ placeholderSymbol=” ” placeholder=”Insert Phone Number …” /><Label text = “{i18n>personName}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Name”/>
<MaskInput id=”input02″ mask=”********************” placeholderSymbol=” ” placeholder=”Insert Name …” >
<rules>
<MaskInputRule />
</rules>
</MaskInput><Label text = “{i18n>personLastName}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Last Name”/>
<MaskInput id=”input03″ mask=”********************” placeholderSymbol=” ” placeholder=”Insert Last Name …”>
<rules>
<MaskInputRule />
</rules>
</MaskInput><Label text = “{i18n>personEmail}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Email”/>
<MaskInput id=”input04” mask = “CCCCCCCCCCCCCCC@people.com” placeholderSymbol = ” ” placeholder = “Insert Email …”>
<rules>
<MaskInputRule maskFormatSymbol = “C” regex = “[a-zA-Z0-9]”/>
</rules>
</MaskInput><Label text = “” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “”/>
<Button icon=”sap-icon://save” press=”onAdd” class=”sapUiSmallMarginBottom” width=”250px” />
</f:SimpleForm>
</VBox>
</l:Grid>
</content>
</IconTabFilter>
<IconTabFilter id=”Tab2″ text=”{i18n>rudContent}” >
<content>
<Table id=”table1″ headerText=”{i18n>lblRead}” items=”{/Peoples}”>
<columns>
<Column popinDisplay=”Inline” minScreenWidth=”Tablet” demandPopin=”true”>
<header>
<Label text=”{i18n>personPhone}”></Label>
</header>
</Column>
<Column popinDisplay=”Inline” minScreenWidth=”Tablet” demandPopin=”true”>
<header>
<Label text=”{i18n>personName}”></Label>
</header>
</Column>
<Column popinDisplay=”Inline” minScreenWidth=”Tablet” demandPopin=”true”>
<header>
<Label text=”{i18n>personLastName}”></Label>
</header>
</Column>
<Column popinDisplay=”Inline” minScreenWidth=”Tablet” demandPopin=”true” hAlign=”Center”>
<header>
<Label text=”{i18n>personEmail}”></Label>
</header>
</Column>
<Column hAlign=”Center”>
<header>
<Label text=”{i18n>lblUpdate}”></Label>
</header>
</Column>
<Column hAlign=”Center”>
<header>
<Label text=”{i18n>lblDelete}”></Label>
</header>
</Column>
</columns>
<ColumnListItem type=”action”>
<cells>
<Text id=”text1″ text=”{Phone}” />
<Text id=”text2″ text=”{Name}” />
<Text id=”text3″ text=”{LastName}” />
<Text id=”text4″ text=”{Email}” />
<Button icon=”sap-icon://user-edit” press=”onOpenDialog” class=”sapUiSmallMarginBottom” />
<Button icon=”sap-icon://delete” press=”onDelete” class=”sapUiSmallMarginBottom” />
</cells>
</ColumnListItem>
</Table>
</content>
</IconTabFilter>
</items>
</IconTabBar>
</content>
</Page>
</pages>
</App>
</mvc:View>
- In WebContent folder create a new folder named controller.
- In controller folder create a new file named CRUD.controller.js
Set this code in CRUD.controller.js file.
sap.ui.define([ “sap/ui/core/mvc/Controller”, “sap/m/MessageToast”,
“sap/m/MessageBox” ], function(Controller, MessageToast, MessageBox) {
“use strict”;
return Controller.extend(“e2e.ui5.controller.CRUD”, {onInit : function() {},
_peopleTrim : function(p) {
return p.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,”).replace(/\s+/g,”);
},onAdd : function() {
var oModel = this.getView().getModel();if (this.getView().byId(“input01”).getValue() == “” || this.getView().byId(“input02”).getValue() == “” ||
this.getView().byId(“input03”).getValue() == “” || this.getView().byId(“input04”).getValue() == “”) {
MessageBox.warning(“All fields are Obligatory”);} else {
var oEntry = {};
oEntry.Phone = this._peopleTrim(this.getView().byId(“input01”).getValue());
oEntry.Name = this._peopleTrim(this.getView().byId(“input02”).getValue());
oEntry.LastName = this._peopleTrim(this.getView().byId(“input03”).getValue());
oEntry.Email = this._peopleTrim(this.getView().byId(“input04″).getValue());oModel.create(‘/Peoples’, oEntry, {success: function(oData, oResponse){
MessageBox.success(oEntry.Phone+” was Created”);
}, error: function(){
MessageBox.error(“Insert Error”);
}
});this.getView().byId(“input01”).setValue(“”);this.getView().byId(“input02”).setValue(“”);
this.getView().byId(“input03”).setValue(“”);this.getView().byId(“input04”).setValue(“”);
this.getView().getModel().refresh();
}
},onDelete : function(oEvent) {
var oModel = this.getView().getModel();
var src = oEvent.getSource();
var path = src.getBindingContext().getPath();
var oData = oModel.getProperty(path);
var sPhone = oData[‘Phone’];oModel.remove(path, {success: function(oData, oResponse){
MessageBox.success(sPhone+” was Deleted”);
}, error: function(){
MessageBox.error(“Delete Error”);
}
});
this.getView().getModel().refresh();
},onUpdate : function(oEvent) {
var oModel = this.getView().getModel();
var oEntry = {};
oEntry.Name = this._peopleTrim(this.getView().byId(“input12”).getValue());
oEntry.LastName = this._peopleTrim(this.getView().byId(“input13”).getValue());
oEntry.Email = this._peopleTrim(this.getView().byId(“input14”).getValue());var sPhone = this.getView().byId(“input11”).getText();
var path = this.getView().byId(“myModel”).getText();oModel.update(path, oEntry, {success: function(oData, oResponse){
MessageBox.success(sPhone+” was Updated”);
}, error: function(){
MessageBox.error(“Update Error”);
}
});
this.getView().getModel().refresh();
this.onCloseDialog();
},onOpenDialog : function(oEvent) {
var oView = this.getView();
var oDialog = oView.byId(“updateDialog”);var oModel = this.getView().getModel();
var src = oEvent.getSource();
var path = src.getBindingContext().getPath();var oData = oModel.getProperty(path);
var sPhone = oData[‘Phone’];
var sName = oData[‘Name’];
var sLastName = oData[‘LastName’];
var sEmail = oData[‘Email’];if (!oDialog) {
oDialog = sap.ui.xmlfragment(oView.getId(), “e2e.ui5.view.UpdateDialog”, this);
oDialog.setModel(this.getView().getModel());
oView.addDependent(oDialog);this.getView().byId(“input11”).setText(sPhone);
this.getView().byId(“input12”).setValue(sName);
this.getView().byId(“input13”).setValue(sLastName);
this.getView().byId(“input14”).setValue(sEmail);
this.getView().byId(“myModel”).setText(path);
}
oDialog.open();
},onCloseDialog : function() {
this.getView().byId(“updateDialog”).close();
this.afterClose();
},afterClose : function() {
this.getView().byId(“updateDialog”).destroy();
}});
});
In view folder create a new file named UpdateDialog.fragment.xml
Put this code in UpdateDialog.fragment.xml file.
<core:FragmentDefinition xmlns=”sap.m”
xmlns:form=”sap.ui.layout.form” xmlns:mvc=”sap.ui.core.mvc” xmlns:core=”sap.ui.core”>
<Dialog id=”updateDialog” title=”{i18n>updateHeader}” contentWidth=”96%” contentHeight=”96%” stretch=”true” >
<content>
<form:SimpleForm editable=”true”>
<Label text=”{i18n>personPhone}” />
<Text id=”input11″ />
<Label text = “{i18n>personName}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Name”/>
<MaskInput id=”input12″ mask=”********************” placeholderSymbol=” ” placeholder=”Insert Name …” >
<rules>
<MaskInputRule />
</rules>
</MaskInput>
<Label text = “{i18n>personLastName}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Last Name”/>
<MaskInput id=”input13″ mask=”********************” placeholderSymbol=” ” placeholder=”Insert Last Name …”>
<rules>
<MaskInputRule />
</rules>
</MaskInput>
<Label text = “{i18n>personEmail}” class = “sapUiSmallMarginTop sapUiTinyMarginBottom” tooltip = “People Email”/>
<MaskInput id=”input14” mask = “CCCCCCCCCCCCCCC@people.com” placeholderSymbol = ” ” placeholder = “Insert Email …”>
<rules>
<MaskInputRule maskFormatSymbol = “C” regex = “[a-zA-Z0-9]”/>
</rules>
</MaskInput>
</form:SimpleForm>
<core:InvisibleText id=”myModel” />
</content>
<beginButton>
<Button type=”Emphasized” text=”Save” press=”onUpdate” />
</beginButton>
<endButton>
<Button text=”Cancel” press=”onCloseDialog” type=”Reject” />
</endButton>
</Dialog>
</core:FragmentDefinition>
In the folder WebContent create a new file named manifest.json
Put this code in manifest.json file.
{
“_version”: “1.3.0”,
“sap.app”: {
“_version”: “1.3.0”,
“id”: “e2e.ui5”,
“type”: “application”,
“i18n”: “i18n/i18n.properties”,
“title”: “{{appTitle}}”,
“description”: “{{appDescription}}”,
“applicationVersion”: {
“version”: “1.0.0”
},
“dataSources”: {
“CRUDOData”: {
“uri”: “http://localhost:8080/People_OData/peopleService.svc/ “,
“type”: “OData”,
“settings”: {
“odataVersion”: “2.0”
}
}
}
},
“sap.ui”: {
“_version”: “1.3.0”,
“technology”: “UI5”,
“deviceTypes”: {
“desktop”: true,
“tablet”: true,
“phone”: true
},
“supportedThemes”: [
“sap_belize, sap_bluecrystal”
]
},
“sap.ui5”: {
“_version”: “1.2.0”,
“rootView”: {
“viewName”: “e2e.ui5.view.CRUD”,
“type”: “XML”,
“id”: “crud”
},
“models”: {
“i18n”: {
“type”: “sap.ui.model.resource.ResourceModel”,
“settings”: {
“bundleName”: “e2e.ui5.i18n.i18n”
}
},
“”: {
“dataSource”: “CRUDOData”
}
},
“autoPrefixId”: true,
“dependencies”: {
“minUI5Version”: “1.34”,
“libs”: {
“sap.ui.core”: {
“minVersion”: “1.34.0”
},
“sap.m”: {
“minVersion”: “1.34.0”
},
“sap.ui.layout”: {
“minVersion”: “1.34.0”
}
}
},
“contentDensities”: {
“compact”: true,
“cozy”: true
}
}
}
- In WebContent folder create a new folder named i18n.
- In i18n folder create a new file named i18n.properties
Put this code in i18n.properties file.
# App Descriptor
appTitle=OpenUI5 CRUD Solution
appDescription=A simple Openui5 CRUD application
# Tabs
listFilter=List View
tableFilter=Table ViewcContent=Create
rudContent=Read/Update/Delete
formAdd=Create PeoplepersonPhone=Phone Number
personName=First Name
personLastName=Last Name
personEmail=EmailupdateHeader=Update People
lblCreate=Create
lblRead=Read People
lblUpdate=Update
lblDelete=Delete
Right click on People_OpenUI5 project and select Run As / Run on Server.
Select your Java Web Tomcat 7 Server and Finish.
Your server should look like this image with both projects running, People_OData and People_OpenUI5.
To execute the application put this url in your browser: http://localhost:8080/People_OpenUI5/
The CRUD application is working Perfect.
Hi,
it looks like there is an error in your index.html.
I append the UI5 Ressources to the lib folder and then I append these script Tags.
http://sap-ui-core.js
sap.ui.getCore().attachInit(function () {
new sap.m.Shell({
app : new sap.ui.core.ComponentContainer({
name : “e2e.ui5”,
height : “100%”
})
}).placeAt(“content”);
});
The App now starts correctly.
But I think there is something missing about the data Bindung Model.
Maybe you have an idea?
Stefan
LikeLike
Hi Stefan, Thanks for your comments. The problem was that the browser is taking the sections as a code injection and this changes the example code. I’ve updated this section of the blog and looks fine.
LikeLike