Sapui5 PDF

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 101

SAPUI5 Training

SAP UI

1
Agenda
SAPUI5 Overview Databinding
Runtime Resources Styling & Theming
Programming Applications Extending SAPUI5
SAPUI5 Developer Studio Notepad Controls
Creating a SAPUI5 Project CVOM Charts
Resource Handling / Localization Optimizing SAPUI5
MVC
SAP UI5 Overview

SAP UI

3
SAP UI Development Toolkit for HTML5

SAP UI Development Toolkit for HTML5


The official long name

SAPUI5
The short name

UI5
Internal name

For official communication the upper two versions have to be used.

UI5 used to be named "Phoenix", it was changed to SAPUI5 in the summer of 2011 because the name
Phoenix was not suitable to be used publicly.
Main UI5 Characteristics

SAPUI5 is an extensible JavaScript-based HTML5 browser


rendering library for Business Applications.
Supports RIA like client-side features based on JavaScript
Supports an extensibility concept regarding custom controls
Allows change of themes for customer branding in an effective manner
Allows usage of own JavaScript and HTML
Uses the jQuery library as a foundation
Fully supports SAP Product standards
Open AJAX compliant and can be used together with/uses other standard
JS libs
Can be used from various platforms (Java, ABAP, etc)
Produced in a release independent code line to enable short shipment
cycles
UI5 Browser Support

Internet Firefox Chrome Safari


Explorer Version 3.6 and Latest version Latest version
Version 9
Version 8 latest version

Internet Explorer 8 is supported with graceful degradation for CSS3 features


like rounded corners, text-shadows, etc.
UI5 Release Plan and Strategy

Development track Release track


Identified by a major and an Identified by a major and an
odd minor version number, even minor version number,
e.g. 1.5.1 e.g. 1.4.1
The versions of this track are
released internally and are The versions of this track are
not meant to be used in released externally. Only
products shipped to these versions are allowed
customers. to be used in production.
UI5 Architecture Overview

UI5 Core
UI5 Core includes base, core and model
modules
Dependency / Class-Loader to load
control libraries
Render manager creates HTML strings
for the instantiated controls
The UI5 Core includes other JavaScript
libraries
jQuery
jQuery UI
data.js
UI5 Control Libraries

sap.ui.commons
Includes bread and butter"
controls like TextField,
TextView, Button
sap.ui.ux3
Includes UX3 patterns, mainly
available in Gold
Reflection design
e.g.: Shell, ExAct and Thing
Inspector
UI5 Control Libraries

sap.ui.table
Includes DataTable control
sap.ui.dev
Experimental controls
not included in all UI5
offerings
UI5 and Extensibility

UI5 allows application developers to

Include their own JavaScript, HTML and CSS into UI5 based pages

Include other JavaScript libraries where UI5 is lacking controls or functionality

Create composite controls from existing UI5 controls

Write new UI libraries and new controls

Write plug-ins for the UI5 core

This way UI5 development groups should not become a bottleneck for application groups in need of a certain functionality.
UI5 Knowledge and Test Resources

Documentation and UI5 Tools support and question channels


Information
SAPUI5 Tools Community
UI5 Wiki

Demo kit

API Documentation

SAPUI5 Versions

Control and code testing

Test Suite
Exercise Create a Simple Application

Create a MatrixLayout with two Labels, two TextFields and a Button


new sap.ui.commons.layout.MatrixLayout
new sap.ui.commons.Label
new sap.ui.commons.TextField
new sap.ui.commons.Button

Add the Labels, the TextFields and the Button to the layout with the
createRow() method
Bonus: Add a press handler to the Button that displays the values of
the TextFields.
attachPress(function() {})
getValue()
Solution to Exercise
var oLayout = new var oButton = new
sap.ui.commons.layout.MatrixLayout({ sap.ui.commons.Button({
width: "100%", text: "Submit"
widths: ["20%", "80%"] });
});
var oLabel1 = new sap.ui.commons.Label({ // add rows with label/textfield to
text: "Given Name" table
}); oLayout.createRow(oLabel1, oTextField1);
var oTF1 = new oLayout.createRow(oLabel2, oTextField2);
sap.ui.commons.TextField({ oLayout.createRow(null, oButton);
id: "given-name", oLayout.placeAt("content");
width: "100%"
}); // add handler to alert textfield values
var oLabel2 = new sap.ui.commons.Label({ oButton.attachPress(function() {
text: "Last Name"
}); var msg = "TextField1: "
var oTF2 = new + oTF1.getValue() + "\n"
sap.ui.commons.TextField({ + "TextField2: " + oTF2.getValue();
id: "last-name", alert(msg);
width: "100%" });
});
Runtime Resources
How to get UI5 resources

UI5 mainly consists of JavaScript, CSS and image files that run in a browser.
Apart from this main offering the runtime files UI5 has many more optional pieces of software
Runtime documentation
Eclipse development tools
Sample apps

In order to get UI5 running on a web page, the UI5 resources need to be loaded by the browser.
These options are available for referencing the UI5 runtime files:
CDN (content delivery network)
Runtime libraries (wars and jars)
SDK
Public Trial

A trial version of the SAPUI5 framework has been released in the SAP Community Network
http://scn.sap.com/community/developer-center/front-end

Not the latest version

includes static JavaScript-Files, war-Files and the Demokit


CDN - Content Delivery Network

The content delivery network provides a ready-to-consume nightly-build version


of UI5. You can include UI5 in any HTML file with the following script tag without
actually deploying UI5.
<script
id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/sdk/sapui5/resources/sap-ui-
core.js"
data-sap-ui-theme="sap_platinum"
data-sap-ui-libs="sap.ui.commons">
</script>
The above example shows the URL which points you to the nightly built, which
includes the newest features but also the newest bugs. To use a stable release,
set the src of the script to:
https://sapui5.hana.ondemand.com/sdk/resources/sap-ui-core.js
https://sapui5.hana.ondemand.com is an external server and you cannot ship
your product referencing this CDN!
Programming Applications
UI5 bootstrap

UI5 pages always have to start with the bootstrap, to initializes the UI5 runtime.

Attributes of the script tag are evaluated and used to configure the runtime
data-sap-ui-libs: the controls libraries to be used, comma-separated
data-sap-ui-theme: the theme
There are more attributes: data-sap-ui-language, data-sap-ui-rtl,
Instead of putting the attributes in the script tag, they can also be added as URL parameters
Application script and UI area

After the bootstrap script tag an <!DOCTYPE html>


<html><head>
"application script" can follow in <meta http-equiv="X-UA-Compatible"
which the UI5 application is written content="IE=edge" />
<script id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-
You create your controls theme="sap_goldreflection"
data-sap-ui-libs="sap.ui.commons">
like layouts and TextFields </script>

Display your controls in an <script>


var btn = new
HTML element called "UI sap.ui.commons.Button({
area" by invoking the text: "Hello World"
});
placeAt method (there btn.placeAt("content");
</script>
can be multiple UI areas)
</head>
When using just one UI area <body class="sapUiBody">
<div id="content"></div>
all controls are connected </body></html>
via the UI5 event manager
Removal of controls

Remove removes the control from the tree it is removed from the UI yet the control instance
still lives and can be reused at a later point in time
Destroy removes the control from the tree and the UI but also the control instance in JavaScript
is freed.
If you want to reuse a control at a later point in time you should keep a reference in a variable and just
remove it.
If you dont need the control anymore, you should destroy it in order to free the resources.
Useful Core functions

sap.ui.getCore() jQuery.sap.domById(id)
get a core instance gets any HTML element with id id
If there is also a UI5 control with id id, the
sap.ui.getCore().byId(id) element returned is the topmost HTML
gets an instance of a UI5 control which element of this UI5 control
was created with id id The topmost HTML element of a UI5
control always has the id defined for the
can be used to retrieve removed UI5 control
controls (even though the id doesnt
jQuery.sap.byId(id)
exist in the DOM anymore)
returns the jQuery object of the DOM
sap.ui.getCore().applyChanges() element with the specified id
carries out and renders the changes for similar to document.getElementById but
UI5 controls directly, so before the gets rid of IE bug which also retrieves
runtime would do it elements with the name of id
Exercise getCore().byId()

Open in your browser https://sapui5.hana.ondemand.com/sdk/#test-


resources/sap/ui/commons/demokit/MatrixLayout.html

Instantiate a MatrixLayout
new sap.ui.commons.layout.MatrixLayout

Add a TextField and a Button control to the MatrixLayout


new sap.ui.commons.TextField
new sap.ui.commons.Button

Add a press event to the button control


Get the TextField value when the button is pressed
sap.ui.getCore().byId().getValue()
Solution to Exercise
<script>
var oMatrix = new sap.ui.commons.layout.MatrixLayout();

var oTextField = new sap.ui.commons.TextField({


width: "200px",
id: "myTextField"
});

var oButton = new sap.ui.commons.Button({


text: "get text",
press: function(oEvent){
alert(sap.ui.getCore().byId("myTextField").getValue();
}
});

oMatrix.createRow(oTextField, oButton);
oMatrix.placeAt("content");
</script>
SAPUI5 Developer Studio
Overview

SAPUI5 Developer Studio is a set of tools for Eclipse that greatly simplify the development process for
UI5 applications and controls, including:
Wizards for project and view/controller creation
Wizards for control development
Code Completion for UI5 controls
TeamProvider for NGAP and BSP repositories
Application preview with an embedded Jetty server
Proxy-servlet to prevent cross-site-scripting errors
More detailed information about the SAPUI5 Developer Studio is available in the SAPUI5 Tools Wiki at
tools.hana.ondemand.com
Installation

Prerequisite: Install the latest Java Development Kit 6, if it is not installed already.
Download and install one of the preconfigured IDEs. If you want to use the SAPUI5 Repository Team
Provider you should choose the 32bit version.
It is also possible to setup Eclipse on your own by using one of the available update sites for Eclipse.
Once Eclipse has been (re)started, the SAPUI5 Eclipse tools should be available. One way to confirm a
successful installation is to check whether you can create a UI Library Project / SAPUI5 Application
Project.
The full installation information is available in the Tools Wiki at:
http://scn.sap.com/community/developer-center/front-end/blog/2013/06/01/how-to-install-a-basic-
development-environment-for-sapui5
Creating a UI5 Project with SAPUI5
Developer Studio
Creating a new SAPUI5 Project

In Eclipse right-click on the project pane to bring up the context menu


(or use the File New entry from the Eclipse menu).
Choose New Project
Creating a new SAPUI5 Project

Select "SAPUI5 Application


Project" in the Wizard.
Click "Next".
Creating a new SAPUI5 Project

Enter the name of the project.


Leave the checkbox "create an initial View"
checked.
Click "Next".
Creating a new SAPUI5 Project

Enter the name of the initial view.


Click "Next".
Creating a new SAPUI5 Project

The last screen shows you a summary of the


project properties.
Click "Finish" to create the new project.
The new Project
Adding a control to the view
Web Application Preview - Jetty
Web Application Preview - Jetty
Exercise Create new UI5 Project

In the SAPUI5 Developer Studio, create a new SAPUI5 Application Project.


Use "Training" as the project name
create an initial JavaScript view named "shell"

Create new folders for JavaScript (/js) and Stylesheets (/css)


Create two empty files; "js/app.js" and "css/style.css"
Modify the head of the index.html to include js/app.js and css/style.css
Add a shell control to the shell.view.js and return it
In the app.js file, get a handle on the Shell control:
var oShell = sap.ui.getCore().byId("main-shell");

Create a Button control and use it in the shell:


var oButton = new sap.ui.commons.Button({text: "Hello"});
oShell.setContent(oButton);
Resource Handling
Localization

UI5 has a built in localization concept, which is aligned to the ResouceBundle


concept in Java

One can get the current language


var sLocale = sap.ui.getCore().getConfiguration().getLanguage();

Get the resource bundle for a given language (if no locale is given, English is
loaded by default)
jQuery.sap.require("jquery.sap.resources");
var oBundle = jQuery.sap.resources({url : sUrl, locale: sLocale});

And then access the texts in the resource bundle


var sText = oBundle.getText(sKey);

You can get the URL for a resource with this:


var sUrl = sap.ui.resource("sap.ui.table", "messagebundle.properties");
Loading JS modules using require

The UI5 framework has built in support for modularizing larger JavaScript
applications.
Instead of defining (and loading) one large chunk of JavaScript code, an application can be split
into smaller parts, which then can be loaded at runtime when they are needed. These smaller,
individual files are called Modules in UI5.
To load a module, the function jQuery.sap.require must be used.
In a module name all . are replaced by / and an .js extension is added to create a path.
So sap.ui.commons.MessageBox will become sap/ui/commons/MessageBox.js

This is an example:

<script>
jQuery.sap.require("sap.ui.commons.MessageBox");

function onPressButton() {
sap.ui.commons.MessageBox.alert("Hi World!");
}
</script>
Modularization using declare
In order to create your own JavaScript Module you need to declare the module
A file becomes a module by calling the jQuery.sap.declare function. This tells the UI5
runtime about the name of the module. UI5 runtime keeps track which modules are
already loaded.
If a module is required (jQuery.sap.require) and it hasnt been loaded before, it is loaded
automatically. While it is carried out, it calls the declare method, so from now on UI5
knows that it has been loaded and when the next require comes about nothing needs to
be done anymore
The declare function checks if the parent namespace object exists and if not, creates it

// declaration of the module. Will ensure that the namespace 'my.useful' exists.
jQuery.sap.declare("my.useful.SampleModule");

// list of dependencies of this module


jQuery.sap.require("sap.ui.core.Core");
jQuery.sap.require("some.other.Module");
jQuery.sap.require("you.can.Also", "list.multiple.Modules", "if.you.Want");

// create the 'main' object of the module


my.useful.SampleModule = {};
Exercise - Localization

Create a new folder "i18n" in the WebContent folder


Add four empty files to that folder i18n.properties, i18n_de.properties,
i18n_fr.properties and i18n_zh.properties
Add a property to each i18n-file
MSG_HELLO_WORLD=Hello World!
MSG_HELLO_WORLD=Hallo Welt!
MSG_HELLO_WORLD=Bonjour tout le monde!
MSG_HELLO_WORLD=\u60A8\u597D\u4E16\u754C <= ISO-8859-1 encoding!
Use the resource bundle to init localization
var oBundle = jQuery.sap.resources({
url : "i18n/i18n.properties",
locale: sap.ui.getCore().getConfiguration().getLanguage()
});
Change the text property of the Button to make use of localization:
text: oBundle.getText("MSG_HELLO_WORLD")
MVC
Basic MVC concept

UI5 provides an MVC concept



Views can contain
XML and HTML (mixed or standalone) sap.ui.core.mvc.XMLView
JavaScript sap.ui.core.mvc.JSView
JSON sap.ui.core.mvc.JSONView
Controller
Can be bound to view
Can be standalone (application controller)
Model: Data binding can be used on the views

Find an MVC in 22 seconds example here.


Basic View / Controller concept

Address.controller. sap.ui.controller("sap.hcm.Address", {
onInit: function() {
js: this.counter = 0;
},
sayHello: function() {
alert("Said hello "
+ this.counter++ + " times.");
}
});
<core:View xmlns:core="sap.ui.core"
xmlns="sap.ui.commons"
Address.view.xml: controller="sap.hcm.Address">
<Panel>
<Button press="sayHello" text="Say Hello" />
</Panel>
</core:View>
sap.ui.xmlview("sap.hcm.Address").placeAt("uiArea"
);
Location logic

Controllers and views use the require/declare logic, so if a controller is referenced like this:
<core:View xmlns:core="sap.ui.core" xmlns="sap.ui.commons"
controller="sap.hcm.Address">
UI5 then checks if you already have defined the controller like this in one of your already processed
application sources
sap.ui.controller("sap.hcm.Address", {
// controller logic goes here
});
If this is not the case then UI5 tries to load this definition from a file that by default is located in your
UI5 resources folder. This applies to views as well.
resources/sap/hcm/Address.controller.js
Controller Events

Currently there are 4 events defined in a You can add handlers for any of these
controller:
for to your controller class:
onInit
sap.ui.controller("sap.hcm.Address", {
fired when the view is first instanciated
onInit: function() {},
onBeforeRendering onBeforeRendering: function() {},
Fired before the view is rerendered onAfterRendering: function() {},
onExit: function() {},
Not before the first rendering though, then onInit is
called
myOwnMethod: function() {}
onAfterRendering });
Fired when the view has been rendered (the HTML is
injected into the document)
onExit
Fired when the controller is destroyed
Can be used to free resources
Example XML View

<core:View xmlns:core="sap.ui.core"
xmlns="sap.ui.commons"
controller="sap.hcm.Address">

<Panel>
<Button press="sayHello"
text="Say Hello" />
</Panel>

</core:View>
Example JSON View

{
"Type":"sap.ui.core.mvc.JsonView",
"controllerName":"sap.hcm.Address",
"content": [{
"Type": "sap.ui.commons.Button",
"id": "MyButton",
"text": "Say Hello",
"press": "sayHello"
}]
}
Example JS View

sap.ui.jsview("sap.hcm.Address", {

getControllerName: function() {
return "sap.hcm.Address";
},

createContent: function(oController) {
var oButton = new sap.ui.commons.Button({ text: "Say Hello" });
/* closure, so controller is known in event handler */
oButton.attachPress(function() {
oController.sayHello();
})
return oButton;
}

});
Databinding
UI5 Data Binding

In UI5, data binding is used to bind UI5 controls to a data source that holds the application
data, so that the controls are updated automatically whenever the application data is
changed.
With two-way-binding the application data is updated whenever the value of a bound control
changes, e.g. through user input.
Data binding supports binding of simple controls like TextField and list type controls like
DataTable and DropdownBox.
See the complete documentation on how data binding works and how to implement it in
an application.
Data Binding Model Implementations
UI5 data binding supports three different model implementations.
JSON model XML model OData model
supports supports XML data supports OData
data in a compliant data
JavaScript supports two way
Object binding creates OData
Notation requests and handles
format OData responses
supports includes the open
two way source library dataJS
binding to handle OData
requests and data

Additionally there is support to use the ResourceModel with UI5 data binding.
Creating a Model Instance

To use data binding in a SAPUI5 applications you will need to instantiate the
appropiate model first. The constructor takes the URL of the model data or
the data itself as the first parameter.
JSON-Model:
var oModel = new sap.ui.model.json.JSONModel(dataUrl);
XML-Model:
var oModel = new sap.ui.model.xml.XMLModel(dataUrl);
OData-Model:
var oModel = new sap.ui.model.odata.ODataModel(dataUrl [, useJSON,
user, pass] );
Assigning the Model

After the model has been created you can assign the model to the Core or specific controls with the
setModel method.
The relevant model for a control is the one which is nearest to it on the path up to the root (UI area).If
there is no model in the root path found the one attached to the core becomes the relevant model
//global model
sap.ui.getCore().setModel(oModel);

//model on UI area level


var oMainArea = sap.ui.getCore().getUIArea("main");
oMainArea.setModel(oModel);
//bind a model to a specific control
var oTable = sap.ui.getCore().byId("table");
oTable.setModel(oModel);
Localization with Data Binding

With the ResourceModel, there is a wrapper for resource bundles that exposes the localized texts as a
model for data binding.
A ResourceModel can be instantiated with a bundleName or a bundleUrl which points to a resource
bundle. When using the bundle name the file must have the .properties suffix.
Example:
var oModel = new sap.ui.model.resource.ResourceModel({
bundleName: "myBundle", // will use the file myBundle_en.properties
locale: "en"
});
var oControl = new sap.ui.commons.Button({
id : "myButton",
text : "{i18n>MY_BUTTON_TEXT}"
});
// attach the resource model with the symbolic name "i18n"
sap.ui.getCore().setModel(oModel, "i18n");
About Binding Paths

{ Absolute binding paths within this model:


company: { /company/name
name: "ACME",
/company/info/employees
info: {
employees: 3 /company/contacts
},
contacts: [{ Relative binding paths within the "/company"
name: context:
"Barbara", name
phone: "873" info/employees
},{
name: "Gerry", contacts
phone: "734"
}] Relative binding paths within an aggregation
} binding of "/company/contacts":
} name
phone
Property Binding

Most of the properties of a control can be bound to model properties.


There are two ways to bind properties to the model, in the constructor with curly braces or using the
bindProperty method.
Curly braces syntax:
var oControl = new sap.ui.commons.TextView({
controlProperty: "{modelProperty}"
});
bindProperty method:
oControl.bindProperty("controlProperty", "modelProperty");
Aggregation Binding

Aggregation binding is used to bind a collection of values, like binding multiple rows to a table. To use
aggregation you will have to use a control that acts as a template.
var oItemTemplate = new sap.ui.core.ListItem({ text: "{aggrProperty}" });
var oComboBox = new sap.ui.commons.ComboBox({
items: { path:"/modelAggregation", template: oItemTemplate }
});

The aggregation binding can also be defined using the bindAggregation method of a control.
oComboBox.bindAggregation( "items", "/modelAggregation", oItemTemplate );
Example for Simple Control

// JSON sample data


var data = {
firstName: "John", lastName: "Doe",
birthday: { day: 01, month: 05, year: 1982 },
address:[{ city: "Heidelberg" }], enabled: true
};

var oModel = new sap.ui.model.json.JSONModel(); // create JSON model instance


oModel.setData(data); // set the data for the model
sap.ui.getCore().setModel(oModel); // assign the model to the core

var oTxt = new sap.ui.commons.TextField("txtField", {


value: "{/firstName}" // binding syntax using curly braces
});

// generic bind method bindProperty(control property, model property)


oTxt.bindProperty("enabled", "/enabled");
Example of Aggregation Binding

var dataObject = { data : [ //create test data


{index: 0, level: "Warning", description: "HAL: I'm sorry, Dave."},
{index: 1, level: "Warning", description: "Windows Boot Manager has a problem."},
// ... shortened example
]};

//create JSON model


var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataObject);
sap.ui.getCore().setModel(oModel);

//create the template control that will be repeated and will display the data
var oRowTemplate = new sap.ui.commons.Message("rowTemplate", {
text: "{description}",
type: "{level}"
});

//create the RowRepeater control


var oRowRepeater = new sap.ui.commons.RowRepeater("rowRepeater", {
rows : { path: "/data", template: oRowTemplate } // bind row aggregation
});
Extended Data Binding Syntax

Instead of just using the token name of a model property you can also use the
extended data binding syntax. This enables you to use formatters and the type
system for property binding and templates, filter and sorters for aggregation
binding.

To use the extended syntax you supply an object literal for the bound
property/aggregation.
Extended property binding: Extended aggregation binding:
{ {
path: path: "/path/to/aggregation",
"/path/to/model/property", template: oItemTemplate,
formatter: fnCallback, sorter: oSorter,
type: oType filters:
} [oFilter1,oFilter2,oFilter3]
}
Formatters

For properties you can supply a formatter function which will be called with the value of the model
property. The return value of the formatter function is used as the value of the bound control.
var oTextField = new sap.ui.commons.TextField({
value: {
path: "/path/to/property"
formatter: upperCase
}
});

function upperCase(sVal) {
return sVal.toUpperCase();
}
Sorter and Filter

When using aggregation binding, you can provide initial sorting and filtering.
var oSorter = new sap.ui.model.Sorter("name", true); // sort descending
var oFilter1 = new sap.ui.model.Filter("name",
sap.ui.model.FilterOperator.StartsWith, "M");
var oFilter2 = new sap.ui.model.Filter("name",
sap.ui.model.FilterOperator.Contains, "Doe");
var oFilter3 = new sap.ui.model.Filter("name",
sap.ui.model.FilterOperator.BT, "A","G"); // name between A and G
var oComboBox = new sap.ui.commons.ComboBox({
items: {
path: "/path/to/aggregation",
template: oItemTemplate,
sorter: oSorter,
filters: [oFilter1,oFilter2,oFilter3]
}
});
Type System
since 1.4.0

Data binding supports the definition of types which can be handed over when binding properties. Bound
properties with a defined type will automatically be formatted when displayed in the UI, input values in
UI controls are parsed and converted back to the defined type in the model.
For each Type you can define the following parameters in the constructor:
format options: Format options define how a value is formatted and displayed in the UI.
constraints (optional): Constraints define how an input value entered in the UI should look like. When
parsing the value will be validated against these constraints.
Type System Example

var oFloat = new sap.ui.model.type.Float(


{ // format options
minFractionDigits: 2,
maxFractionDigits: 2
},
{ // contraints
maximum: 10
});
var oText = new sap.ui.commons.TextField({
value: {
path: "/sliderValue",
type: oFloat
}
});
Input Validation

To catch invalid user input, you can register the following handlers to the SAPUI5 Core.
attachFormatError
attachParseError
attachValidationError
attachValidationSuccess

Example:
sap.ui.getCore().attachValidationError(function(oEvent) {
var oElement = oEvent.getParameter("element");
if (oElement.setValueState) {
oElement.setValueState(sap.ui.core.ValueState.Warning);
}
});
OData - Open Data Protocol

Based on HTTP, Atom Pub format and JSON


Enables provision of data services based REST principles
Released under open specification promises by Microsoft
Defines data queries using URLs constructed with specific rules
Defines data formats representing resources like collections, entries, etc. in either
Atom or JSON format

OData URL structure:


http://services.odata.org/OData/OData.svc/Category(1)/Products?
$top=2
Service Root URI Resource path Query options
Example code for OData

// the backend OData service URL


var uri =
"http://ldai1bld.wdf.sap.corp:50069/
sap/imsample/st/odata_server2/exact?
sap-client=005";

// create OData model from URL


var oModel = new sap.ui.model.odata.ODataModel(uri, true);
var oTable = new sap.ui.table.DataTable({ // create Table UI
columns : [
{label: "Name", template: "Description", sortProperty:
"Description" },
{label: "Amount", template: "Amount", sortProperty: "Amount" }
]
});
oTable.setModel(oModel); // bind model to Table
oTable.bindAggregation( "rows", "InvoiceSpendOfVendorGroups" );
oTable.placeAt("content"); // place model onto UI
Styling and Theming
Adjusting styles

In some cases one needs to adjust parts of the theme using CSS

One can add <style> or <link> tags in the HTML <head> tag to include new styles
These styles are always processed after the UI5 CSS from the themes
As the last processed CSS wins in case of multiple same CSS rules, the custom CSS always overwrites
the standard UI5 CSS
The parts to be overwritten can be determined using tools like Firebug
It is also important to know that the id given to a control is also the id that the topmost HTML element
of this control gets. Thus, this id can be used as a reference in CSS

Using the addStyleClass method that every UI5 control has


One can add a CSS class to the top level HTML element of the UI5 control
See an example here
UI5 Theming

See general concept


Based on CSS
In addition: CSS Parameters (see next slide)
CSS files are separated by control at development time
Additionally: global.css, shared.css
Every theme uses base theme CSS plus specific theme related
CSS files on top
Generator merges files and appends specific themes to base
theme
Replaces CSS Parameter usages
Optional compression/optimization
Automatic right-to-left generation (For RTL languages like Hebrew)
One CSS file per control library (library.css)
UI5 Framework handles theme switching at runtime
UI5 Theming: CSS Parameters
UI5 offers two main options to adjust themes
Adjusting standard CSS directly with standard tools
Changing parameters for the main features of a theme
Parameters
Some values (often: colors) used for different elements
Parameters: write once, reference often
Parameters are mixed into the CSS of the controls.
The parameters are set in central files (Those defined in global.css/shared.css are
available globally / in whole control library)
Using the Java based generator the parameters values are inserted and CSS only files
are generated (note: Generator step is needed when using CSS parameters, this is not
the case if one wants to change the CSS only files)

@-sap-parameters {
sapUiTextColor: #000000; /* text color is 'black' */
[...]
}
button {
color: -sap-par(sapUiTextColor); /* current text color */
[...]
}
UI5 Theming: CSS Parameters II

Original parameters can be read at runtime with a JavaScript API


This allows tranfering UI5 theme parameters to own HTML parts
Especially useful when one uses technology which cannot be influenced by CSS directly:
Canvas
WebGL

jQuery.sap.require("sap.ui.core.theming.Parameters");
var myColor = sap.ui.core.theming.Parameters.get("sapUiSemanticCriticalColor"))
Control Style and Themes: Supported themes
Themes shipped with UI5:

Gold Reflection

Blue Crystal

Older Themes that are


not used anymore
Platinum:
specification

Ux Target Design:
specification


See all these themes
showcased in an example
Extending UI5
Inclusion of external JS libraries

If UI5 doesnt provide controls or behaviours that other JavaScript libraries offer, these libraries can be
included into the UI5 based pages
Some JS libraries are already included in UI5 and used by UI5 runtime and can be used without additional loading
jQuery, jQuery UI
dataJS, a Microsoft driven oData library which handles requests and takes care of creating and handling requests in JSON
and XML format

Other libraries need to be loaded separately, currently other libraries of interest are
Flot, a <canvas> based jQuery plug in for displaying data sets using plot graphics
Protovis, an SVG based graphical library to visualize data sets


Inclusion of external JS libraries

To show how to load and use an external library, we take a look at an


example using jQuery flot

One can place the script tags for the library just behind the UI5 bootstrap script tag I n
the HTML <head> tag

the library can be download and made part of the application project
For pie chart support you need also the flot.pie.js plugin

You can see a working pie chart example here


Inclusion of external JS libraries

Most libraries require an // create the HTML control which will be a placeholder
staring point or a var oHTML = new sap.ui.core.HTML({
placeholder id: "pieContainer,
content: "<div id=pieContainer'

This HTML element can style=\"height:500px;width: 500px\"></div>"


be provided by using the });
cores HTML control /* starts rendering when the placeholder is rendered */
oHTML.attachAfterRendering(

HTML controls content function(oEvent){

is only rendered when /* chart data array */


the page is loaded or var data = [];
after an event handler is /* rendering pie chart */
finished $.plot($("#pieContainer"), data,
{

The HTML control series: {


provides an pie: {
afterRendering event, show: true
which indicates when }
the HTML control is }
finished rendering
}
}
);
Notepad Controls
Since 1.4.0
Overview

There are two approaches to develop UI5 Controls, either with tool support, or native in the
editor. This section deals with creating custom controls with the extend method.

Since an IDE is not needed to create new controls with the extend method these controls have
been named "Notepad Controls".
Technically, this functionality is not restricted to Controls. Arbitrary objects derived from
sap.ui.base.Object can be created or extended.
The extend Method

The extend() method is available on all Controls (and the base classes) and is used to define
a new subclass.
Creating a new control:
sap.ui.core.Control.extend(sName, oDefinition);

Creating a new Control which inherits from Button:


sap.ui.commons.Button.extend(sName, oDefinition);
The parameters to this function are the name and the definition of the new control type. The definition
part contains information about the control API, which properties, aggregations, events, etc. the control
has and the implementation of the control methods.
Some methods such as the getters and setters for the properties and aggregations or the methods for
attaching/detaching event handlers are automatically created by UI5.
Basic Example

// set the name of the new Control type to "my.Hello"


sap.ui.core.Control.extend( "my.Hello", {
metadata: { // the Control API
properties: {
name: "string" // setter and getter are created behind the scenes
}
},
renderer: function( oRm, oControl ) {
// the part creating the HTML
oRm.write( "<span>Hello " );
// write the Control property 'name', with XSS protection
oRm.writeEscaped( oControl.getName() );
oRm.write( "</span>" );
}
});
new my.Hello({ name: "UI5" }).placeAt( "content" );
Control Definition

The definition object for a custom control may contain metadata, public and private methods, event
handler and the renderer.
sap.ui.core.Control.extend("TestControl", {
metadata: { // defines the properties, aggregations, events
properties: {},
events: {},
aggregations: {}
},
publicMethod: function() {}, // all methods are public
_privateMethod: function() {}, // private methods are prefixed with _
init: function() {} // called when control is instantiated
onclick: function(e) {}, // event handler
renderer: function(rm, oControl) {} // creates the html for the control
});
Control Metadata

The metadata in the control definition consists of objects for the control
properties, events and aggregations.
Properties Example
type: The data type of the Control properties: {
property. title: "string",
btnTxt: { defaultValue:
string for a string property (default)
"Search" },
int or float for number properties showLogoutButton: {
int[] for an array of integers, string[] for type: "boolean",
an array of strings, etc. defaultValue: true
},
sap.ui.core.CSSSize for a custom-defined
type width: {
type: "sap.ui.core.CSSSize",
defaultValue: The default value of defaultValue: "50px"
the property. (undefined if not set) }
}
Control Metadata
continued

Events Aggregations
Events are specified by the event Aggregations and associations are
name only. In many cases there is defined by their name, along with an
nothing to configure about them, object that can have a type, a
so just give an empty object. multiple flag and a singularName.
Controls can enable events to be aggregations: {
interrupted by the application, acceptButton:
using the enablePreventDefault "sap.ui.commons.Button",
flag. worksetItems: {
type:
events: {
logout: {}, "sap.ui.ux3.NavigationItem",
close: { multiple: true,
enablePreventDefault : true singularName : "worksetItem"
} }
} }
Control Methods

After the metadata is defined, you can add any method implementations to your new Control. The
method names can be chosen freely, some method names must be avoided though:
Names of methods that are provided by a super class.
Methods starting with set, get, insert, add, remove or indexOf may collide with setters/getters for properties or
aggregations you defined.
Methods starting with attach, detach or fire may collide with methods created for events.
There are some method names you may use but which have a special meaning:
on...: Methods starting with "on" are event handlers that are automatically bound to browser events.
init: Is the name of the initialization function called right after Control instantiation.
renderer: The name of the function that creates the HTML for the control.
Control Methods
continued

Public / private methods


The convention is that private methods start with an underscore. All other methods are considered
public.
init Method
The init() method is invoked by the UI5 core for each control instance right after the constructor. Use
this to set up things like internal variables or sub-controls of a composite. This method is considered
private and only to be called by the UI5 core.
Event handler methods
Methods that have a name starting with on are reserved for event handlers. For common events such as
click or keydown, browser event handlers for these methods are registered automatically by the UI5
core.
Control Methods
Examples

// public method // init method, invoked when control


divide: function(x, y) { // is instantiated
if (this._checkForZero(y)) { init: function() {
throw new Error("Second parameter may not this._bSearchTriggered = false;
be zero"); this._oSearchBtn =
} new sap.ui.commons.Button(
return x / y; this.getId() + "-searchBtn",
}, { text: "Search" }
);
// private method
},
_checkForZero: function(y) {
if (y === 0) { // event handler
return true; onclick: function(e) {
} alert("Control " + this.getId()
return false; + " was clicked.");
}, }
Control Renderer

The renderer method is Example:


responsible for creating the renderer: function(oRm, oCtrl) {
HTML structure that makes up oRm.write("<div");
the control. It is different oRm.writeControlData(oCtrl);
from the other methods, as it oRm.addStyle("width",
is a static one, so the this oCtrl.getSize());
keyword is not available. oRm.writeStyles();
Instead, a control instance and oRm.addClass("myClass");
a RenderManager instance are oRm.writeClasses();
given to the method. oRm.write(">");
oRm.writeEscaped(oCtrl.getText());
oRm.write("</div>");
If an existing renderer should }
be used without modification, Using an existing renderer:
you can give the name of this renderer:
renderer class. "sap.ui.commons.ButtonRenderer"
CVOM Charts
CVOM Chart Types

Bar Events
sap.viz.ui5.Bar selectData ( oControlEvent )
Line
sap.viz.ui5.Line CVOM API Reference
Pie
sap.viz.ui5.Pie

Combination
sap.viz.ui5.Combination
Exercise CVOM Pie Chart
Extend the UI5 bootstrap to the CVOM Chart library
sap.service.visualization

Create an array with test data and set it to a JSON Model


new sap.ui.model.json.JSONModel();

Bind the model to a DataTable


new sap.ui.table.DataTable();

Define a SimpleDMDataset and set it to the DataTable


new sap.service.visualization.dataset.SimpleDMDataset();

Instantiate a Pie CVOM Chart


new sap.service.visualization.chart.Bar();
Solution to Exercise

var oChartData = [ { Country : "Canada", profit: 341.25, revenue:410.87 },


{ Country : "China", profit: 133.82, revenue:338.29},
{ Country : "France", profit: 348.76, revenue:487.66 },
{ Country : "Germany", profit: 217.29, revenue:470.23 },
{ Country : "India", profit: 117.00, revenue:170.93 },
{ Country : "United States", profit: 609.16, revenue:905.08 }];
var oDataTable = new sap.ui.table.DataTable();
var oControl = new sap.ui.commons.TextView().bindProperty("text","Country");

oDataTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({ text: "Country"}),
template : oControl
}));

oControl = new sap.ui.commons.TextView().bindProperty("text","profit");

oDataTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({ text: "profit"}),
template : oControl
}));
Solution to Exercise

oControl = new sap.ui.commons.TextView().bindProperty("text","revenue");

oDataTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({ text: "revenue"}),
template : oControl
}));

var oJSONModel = new sap.ui.model.json.JSONModel();

oJSONModel.setData({ chartData: oChartData });

oDataTable.setModel(oJSONModel);
oDataTable.bindRows("chartData");

var oDataset = new sap.service.visualization.dataset.SimpleDMDataset();

oDataset.setDataTable(oDataTable);

Optimizing UI5 Files


Reducing the number of JavaScript files

sap-ui-core.js
loads library.js file for each used library.
loads control behaviour and rendering files when
control is instantiated.
only needed code is loaded
many requests
sap-ui-core.js: 99 requests, 1,06 MB, 831ms

sap-ui-core-all.js
loads the complete library, including the code for all
controls
less requests
bigger filesize

sap-ui-core-all.js: 18 requests, 1,54 MB, 439ms


Configure UI5 download tool

The download tool creates merged js files with all Usage:


desired modules. Load your application page and
navigate through it (, to load all used
You can mix such a merged file with the dynamic modules)
on-demand approach: load a big file with the
Press CTRL-ALT-SHIFT-P
most common modules and let UI5 load the others (UI5 Technical Info)
on demand.
Expand the list of loaded modules,
Please be aware, that the above tool link creates select and copy it
the download configuration for the nightly build. Paste your module list into the empty
white
text area on the right hand side
Download and Save the custom
modules
Package the custom module into your
application and load it in your page
instead
of the sap-ui-core.js
Thank you!

You might also like