30 minutes
In this exercise, we will build a User Interface based on SAP UI5 so that users can create a booking from the UI of our app.
This exercise is structured into two parts:
In this part, we will import the locally developed code of exercise 1 to 3 into SAP Web IDE. The database and service components will be deployed to Cloud Foundry.
- Launch SAP Web IDE. You will be prompted to login, provide your credentials (Email and Password) provided by the instructors of SAP TechEd 2018 session CNA375. Here the example email is
[email protected]
- replace XXX with the number provided for you.
- Choose
File
->Git
->Clone Repository
.
- If you completed part B of exercise 3, enter the repository URL that you noted down in exercise 3 part B's step 7.
Your URL should look like: https://git.hana.ondemand.com/di26c7ouv0/cnaXXX
, where XXX is your personal number provided by the session instructors.
If you skipped part B of exercise 3, then provide this URL, https://git.hana.ondemand.com/di26c7ouv0/cna375ex3
, and click clone
.
- You will be asked to enter the credentials once again. Enter the credentials (email and password) provided by the CNA375 session owners. The authentication in step 1 is for the SAP WebIDE access, and here in this step it authorizes access to the git repository.
- Now we will be able to see the code that was cloned into our SAP Web IDE workspace.
- Right click on your project, choose
Project
and then click onProject Settings
.
- Choose the
Cloud Foundry
tab and from the list of dropdown options choose the url,https://api.cf.eu10.hana.ondemand.com
.
- You will be prompted to login. Enter your Cloud Foundry log on credentials (same email and password).
The organization and space will be automatically be populated as shown. Click on Save
.
- Open package.json file from the root folder,
<git_repo_name>/package.json
, and remove the highlighted lines shown below. These are lines specific to SQLite database that was used locally. As we deploy the database artifacts into SAP HANA, these lines must be removed.
- Open the file
db/src/.hdiconfig
and change the first property plugin_version from 2.0.30.0 to 2.0.2.0
Now right click on the db
folder of the project and click on Build
as shown. This takes roughly about a minute.
- The log output can be seen in the console as below.
- In order to view the created database tables, we enable SAP HANA Database Explorer on SAP Web IDE. To do this goto
Tools
menu on the top -> choosePreferences
-> clickFeatures
in the left tabs -> enterhana database
in the search field -> Switch ON theSAP HANA Database Explorer
as shown and clickSave
.
- The screen will prompt to Refresh. Click
Refresh
.
- After the reload we will have the aditional
database explorer
tab on the left(highlighted in the screenshot). Click on this tab and the Database Explorer Connectivity popup can be seen as below:
- Click
Connect
button in the above image and add a HDI database container. If you are using this tab for the first time, you will have a popup as below. ClickYes
:
Else Choose the + button shown below to add a database:
- Click on the HDI Container with the name of your project and the organization
TechEd2018_CNA375-TechEd
and clickOK
.
- Click on
Tables
and then on any table to see the database columns:
- Click on
Open Data
button to see the table contents:
- Switch to the
Development
tab of Web IDE and right click onmta.yml
file from the root folder and clickOpen MTA Editor
.
Click on srv
tab and then scroll down to Requires
section and click on cloud-sample-spaceflight-node-uaa(resource)
. Then press the delete button as shown and save the file.
- Right click the
srv
folder and chooseBuild
and then clickBuild
again.
The log output can be seen in the console as below.
Include the following lines to the srv/package.json
file. Note that this package.json
file resides inside the srv
folder.
"cds": {
"data": {
"driver": "hana",
"hana": {
"tag": "hana"
}
}
}
This file now looks as shown below with the added lines highlighted:
- Right click the
srv
folder and chooseRun
and then chooseRun as Node.js Application
. This takes a couple of seconds as it deploys the service to cloud foundry.
The running Node.js application can be seen here. Note down this URL to be used in the next step.
On clicking the URL above we can see the service information.
Click on the /booking
service to access the XML metadata information of the oData service exposed. In addition the URL now is changed to http://<service_URL>/booking/$metadata
Change the $metadata part of the URL to something meaningful from our exposed service such as Planets to see the JSON response:
- Goto SAP Cloud Platform destinations to create a destination. Press
New Destination
Provide the Name
as cna375-xxx
, where xxx is the number provided for you by the session instructors. Provide URL
as the one noted from the last step along with the path /booking
as shown in the screenshot. Click on New Property
button twice to include the two properties WebIDEEnabled
and WebIDEUsage
with values true
and odata_gen
respectively.
Leave the rest of the populated fields as it is and click Save
.
Congratulations, we successfully imported and built our data model and node service in part A of this exercise.
- Right click our project and choose
New
and thenHTML5 Module
.
- Choose the
SAPUI5 Application
template.
- Enter Module Name as
ui
and Namespace asspace.itineraries.company
.
- Give the View Name as
App
and click onFinish
.
- The UI module code is generated. Expand the
ui
folder and thenwebapp
folder. Within view and controller folders you can see two generated files:App.view.xml
andApp.controller.js
- Open the
manifest.json
file present in the webapp folder under ui. Click onDescriptor Editor
below and then choose theDataSources
sub-tab above. Click the + button to add a data-source.
- Choose
Service URL
from the tabs on the left. In the dropdown menu, select the destination that you created in the last step of part A of this exercise. Note that destinations created by all participants appear in the dropdown menu. In case your destination does not appear here, you may have to refresh the SAP Web IDE.
Under relative path enter /
and click on Test
. Once the test is successful the button gets disabled. The service is now selected and click on Next
.
- Leave the selection as
Use default model
and clickNext
.
- Click
Finish
. Save the manifest.json file.
Now go the the raw form of the manifest.json
with clicking on CodeEditor at the bottom:
Navigate to top-level property sap.ui5
(around row number 68) and then to the property models
. Replace the value of the groupId
setting to "$auto"
and add a new setting "autoExpandSelect" : true
. Both together look like this:
"groupId": "$auto",
"autoExpandSelect" : true
- Under
view
folder, replace the code inApp.view.xml
with the below code:
<mvc:View controllerName="space.itineraries.company.ui.controller.App" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<Carousel>
<mvc:XMLView viewName="space.itineraries.company.ui.view.ListBookings"/>
<mvc:XMLView viewName="space.itineraries.company.ui.view.CreateBooking"/>
</Carousel>
</mvc:View>
This declares two XML Views: ListBookings
and CreateBooking
. We will create them in the next steps.
- Right click on the
view
folder and choosenew
->SAPUI5 view
.
- Give the name as
CreateBooking
, click onNext
and thenFinish
. Repeat step 11 to create another SAPUI5 view and this time give the name of the view asListBookings
.
- Note that 2 additional files for CreateBooking and ListBookings are added under view and controller folders for each respectively.
- Right click on the
ListBookings.view.xml
file and chooseOpen Layout Editor
.
This will open the modeling pane for the view as shown:
Click on the highlighted blue XML Page to view the Page properties. Provide a Title such as Space Itineraries Company
for the page title property on the right side.
- In the
Search for control
field enter the valuelist
and drag and drop theList
control on the view.
- Select the list item on the view, by clicking on the
List Item 1
object and verify that it is selected by checking that the control chain containsStandard List Item
:
On the right side panel, click on the entity set
button and choose the OData service that was added in steps 6 to 9.
Select the option Define entity set and set the selected control as template
.
For the field Entity Set
select the value /Bookings
from the drop-down.
Click the OK
button to save the configuration.
Adapt the property Title
by clicking on the Bind this property
button on the right side of the property.
A window with all the data fields and a text area appear to customize the title. Compose a value such as: {CustomerName} travels from {Itinerary/Name}
. Double click the data fields to use them as a part of the text.
Repeat the same process for the property Description
. Enter the value Booking number {BookingNo} on {DateOfTravel}
.
And lastly, change the type
of the list item from the properties pane to Inactive
and save the file.
- Now we will add a Refresh button. Search for the control
Button
in the list on the left-hand side of the pane and drag and drop it to the upper right corner of the view:
Let's move to the properties of the button. First, change the text of it to Refresh
and move to the Events
for our button:
Add behaviour for the Press
event with choosing the option New function
:
In the dialog enter for the function name the value onRefresh
and click OK:
Now open the menu for the Press
event once again and choose Open in Editor
:
This will open the ListBookings.controller.js
with a focus on the newly created onRefresh
function. We will add the actual refresh logic and the function should look like this:
onRefresh: function (oEvent) {
this.byId("list0").getBinding("items").refresh();
}
- Let us move on to the second view
CreateBooking
. Open theCreateBooking.view.xml
file by double-clicking on it in the file structure. Replace the content with the code snippet below:
<mvc:View controllerName="space.itineraries.company.ui.controller.CreateBooking" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:semantic="sap.m.semantic" xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<App>
<pages>
<Page id="page" title="{i18n>AppTitle}">
<f:SimpleForm id="form" editable="true" layout="ResponsiveGridLayout" title="{i18n>createBookingPanelTitle}" labelSpanXL="4" labelSpanL="3"
labelSpanM="4" labelSpanS="12" adjustLabelSpan="false" emptySpanXL="0" emptySpanL="4" emptySpanM="0" emptySpanS="0" columnsXL="2"
columnsL="1" columnsM="1">
<f:content>
<Label text="Name" labelFor="customerNameInput"/>
<Input id="customerNameInput" value="{CustomerName}"/>
<Label text="Email" labelFor="emailInput"/>
<Input id="emailInput" value="{EmailAddress}"/>
<Label text="Choose a journey" labelFor="selectedItineraryId"/>
<Select id="selectedItineraryId" items="{/Itineraries}" selectedKey="{Itinerary_ID}">
<core:ListItem key="{ID}" text="{Name}"/>
</Select>
<Label text="Date of travel" labelFor="dateOfTravel"/>
<DatePicker id="dateOfTravel"
value="{ path: 'DateOfTravel', type:'sap.ui.model.type.Date', formatOptions: { style: 'medium', stringParsing: true }}"/>
<Label text="Number of passengers" labelFor="numPassengers"/>
<Input id="numPassengers" value="{NumberOfPassengers}"/>
<Label text="Credit card number" labelFor="creditCard"/>
<Input id="creditCard" value="{PaymentInfo_CardNumber}"/>
<Label/>
<Button text="{i18n>bookButtonText}" press="onBook" width="15%"/>
</f:content>
</f:SimpleForm>
</Page>
</pages>
</App>
</mvc:View>
- Open the
CreateBooking.controller.js
file undercontroller
folder and replace the contents with the following code snippet and save the file:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast"
], function (Controller, MessageToast) {
"use strict";
return Controller.extend("space.itineraries.company.ui.controller.CreateBooking", {
_createNewEntity: function (oView, isOnInit) {
var oModel = isOnInit ? this.getOwnerComponent().getModel() : oView.getModel(),
oListBinding = oModel.bindList("/Bookings", undefined, undefined, undefined, {
$$updateGroupId: "updateGroup"
});
var oContext = oListBinding.create({
BookingNo: (Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10)).toUpperCase(),
CustomerName: "",
EmailAddress: "",
DateOfTravel: new Date().toJSON(),
Cost: Math.floor((Math.random() * (3000 - 1000) + 1000)).toString(),
NumberOfPassengers: 0,
Itinerary_ID: "",
PaymentInfo_CardNumber: ""
});
oView.setBindingContext(oContext);
},
onInit: function () {
this._createNewEntity(this.getView(), true);
},
onBook: function () {
var that = this,
oView = this.getView(),
oModel = oView.getModel();
oModel.submitBatch("updateGroup");
oView.getBindingContext().created().then(function () {
MessageToast.show("Booking created");
that._createNewEntity(oView, false);
});
}
});
});
- Under i18n folder, replace the contents in
i18n.properties
file with the following values and save the file:
createBookingPanelTitle=Create a booking
bookButtonText=Book
AppTitle=Space Itineraries Company
- Now right click the
ui
folder andRun as a Web Application
.
- Now bookings can be viewed and created from the UI. Note that initially the bookings list may be empty as there are no bookings created yet.
Congratulations. We just built a UI for our Space travel bookings app. In the next exercise we will build and deploy the full-stack application to SAP Cloud Platform.
Click here to continue with Exercise 5.