Вы находитесь на странице: 1из 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
Explorer
Version 9
Version 8

Firefox

Chrome

Safari

Version 3.6 and


latest version

Latest version

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

Identified by a major and an


odd minor version number,
e.g. 1.5.1

The versions of this track are


released internally and are
not meant to be used in
products shipped to
customers.

Release track

Identified by a major and an


even minor version number,
e.g. 1.4.1

The versions of this track are


released externally. Only
these versions are allowed
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
Information

UI5 Wiki

Demo kit

API Documentation

SAPUI5 Versions

Control and code testing

Test Suite

UI5 Tools support and question channels

SAPUI5 Tools Community

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


sap.ui.commons.layout.MatrixLayout({
width: "100%",
widths: ["20%", "80%"]
});
var oLabel1 = new sap.ui.commons.Label({
text: "Given Name"
});
var oTF1 = new
sap.ui.commons.TextField({
id: "given-name",
width: "100%"
});
var oLabel2 = new sap.ui.commons.Label({
text: "Last Name"
});
var oTF2 = new
sap.ui.commons.TextField({
id: "last-name",
width: "100%"
});

var oButton = new


sap.ui.commons.Button({
text: "Submit"
});
// add rows with label/textfield to
table
oLayout.createRow(oLabel1, oTextField1);
oLayout.createRow(oLabel2, oTextField2);
oLayout.createRow(null, oButton);
oLayout.placeAt("content");
// add handler to alert textfield values
oButton.attachPress(function() {
var msg = "TextField1: "
+ oTF1.getValue() + "\n"
+ "TextField2: " + oTF2.getValue();
alert(msg);
});

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-uicore.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


"application script" can follow in
which the UI5 application is written

You create your controls


like layouts and TextFields

Display your controls in an


HTML element called "UI
area" by invoking the
placeAt method (there
can be multiple UI areas)

When using just one UI area


all controls are connected
via the UI5 event manager

<!DOCTYPE html>
<html><head>
<meta http-equiv="X-UA-Compatible"
content="IE=edge" />
<script id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-uitheme="sap_goldreflection"
data-sap-ui-libs="sap.ui.commons">
</script>
<script>
var btn = new
sap.ui.commons.Button({
text: "Hello World"
});
btn.placeAt("content");
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body></html>

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()

get a core instance

sap.ui.getCore().byId(id)

gets an instance of a UI5 control which


was created with id id
can be used to retrieve removed
controls (even though the id doesnt
exist in the DOM anymore)

sap.ui.getCore().applyChanges()

carries out and renders the changes for


UI5 controls directly, so before the
runtime would do it

jQuery.sap.domById(id)

gets any HTML element with id id

If there is also a UI5 control with id id, the


element returned is the topmost HTML
element of this UI5 control

The topmost HTML element of a UI5


control always has the id defined for the
UI5 control

jQuery.sap.byId(id)

returns the jQuery object of the DOM


element with the specified id

similar to document.getElementById but


gets rid of IE bug which also retrieves
elements with the name of id

Exercise getCore().byId()

Open in your browser https://sapui5.hana.ondemand.com/sdk/#testresources/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-basicdevelopment-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)

JavaScript

sap.ui.core.mvc.JSView

JSON

sap.ui.core.mvc.JSONView

sap.ui.core.mvc.XMLView

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.
js:

sap.ui.controller("sap.hcm.Address", {
onInit: function() {
this.counter = 0;
},
sayHello: function() {
alert("Said hello "
+ this.counter++ + " times.");
}
});

<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>

sap.ui.xmlview("sap.hcm.Address").placeAt("uiArea"
);

Address.view.xml:

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


controller:

onInit

onBeforeRendering

Fired before the view is rerendered

Not before the first rendering though, then onInit is


called

onAfterRendering

fired when the view is first instanciated

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

You can add handlers for any of these


for to your controller class:

sap.ui.controller("sap.hcm.Address", {
onInit:
function() {},
onBeforeRendering: function() {},
onAfterRendering: function() {},
onExit:
function() {},
myOwnMethod:
});

function() {}

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

supports
data in a
JavaScript
Object
Notation
format

supports
two way
binding

XML model
supports XML data
supports two way
binding

OData model
supports OData
compliant data
creates OData
requests and handles
OData responses
includes the open
source library dataJS
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

{
company: {
name: "ACME",
info: {
employees: 3
},
contacts: [{
name:
"Barbara",
phone: "873"
},{
name: "Gerry",
phone: "734"
}]
}
}

Absolute binding paths within this model:

/company/name
/company/info/employees
/company/contacts

Relative binding paths within the "/company"


context:

name
info/employees
contacts

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 aggregation binding:
Extended property binding:

{
path:
"/path/to/model/property",
formatter: fnCallback,
type:
oType
}

{
path:
"/path/to/aggregation",
template: oItemTemplate,
sorter:
oSorter,
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


staring point or a
placeholder

// create the HTML control which will be a placeholder


var oHTML = new sap.ui.core.HTML({
id: "pieContainer,
content: "<div id=pieContainer'

This HTML element can


be provided by using the
cores HTML control

style=\"height:500px;width: 500px\"></div>"

});
/* starts rendering when the placeholder is rendered */
oHTML.attachAfterRendering(

function(oEvent){

HTML controls content


is only rendered when
the page is loaded or
after an event handler is
finished

/* chart data array */


var data = [];

/* rendering pie chart */


$.plot($("#pieContainer"), data,
{

The HTML control


provides an
afterRendering event,
which indicates when
the HTML control is
finished rendering

series: {
pie: {
show: true
}
}
}
}
);

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
type: The data type of the Control
property.

string for a string property (default)

int or float for number properties

int[] for an array of integers, string[] for


an array of strings, etc.

sap.ui.core.CSSSize for a custom-defined


type

defaultValue: The default value of


the property. (undefined if not set)

Example

properties: {
title: "string",
btnTxt: { defaultValue:
"Search" },
showLogoutButton: {
type: "boolean",
defaultValue: true
},
width: {
type: "sap.ui.core.CSSSize",
defaultValue: "50px"
}
}

Control Metadata
continued

Events

Aggregations

Events are specified by the event


name only. In many cases there is
nothing to configure about them,
so just give an empty object.

Aggregations and associations are


defined by their name, along with an
object that can have a type, a
multiple flag and a singularName.

Controls can enable events to be


interrupted by the application,
using the enablePreventDefault
flag.

events: {
logout: {},
close: {
enablePreventDefault : true
}
}

aggregations: {
acceptButton:
"sap.ui.commons.Button",
worksetItems: {
type:
"sap.ui.ux3.NavigationItem",
multiple: 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
divide: function(x, y) {
if (this._checkForZero(y)) {
throw new Error("Second parameter may not
be zero");
}
return x / y;
},

// private method
_checkForZero: function(y) {
if (y === 0) {
return true;
}
return false;
},

// init method, invoked when control


// is instantiated
init: function() {
this._bSearchTriggered = false;
this._oSearchBtn =
new sap.ui.commons.Button(
this.getId() + "-searchBtn",
{ text: "Search" }
);
},

// event handler
onclick: function(e) {
alert("Control " + this.getId()
+ " was clicked.");
}

Control Renderer

The renderer method is


responsible for creating the
HTML structure that makes up
the control. It is different
from the other methods, as it
is a static one, so the this
keyword is not available.
Instead, a control instance and
a RenderManager instance are
given to the method.
If an existing renderer should
be used without modification,
you can give the name of this
renderer class.

Example:

renderer: function(oRm, oCtrl) {


oRm.write("<div");
oRm.writeControlData(oCtrl);
oRm.addStyle("width",
oCtrl.getSize());
oRm.writeStyles();
oRm.addClass("myClass");
oRm.writeClasses();
oRm.write(">");
oRm.writeEscaped(oCtrl.getText());
oRm.write("</div>");
}

Using an existing renderer:

renderer:
"sap.ui.commons.ButtonRenderer"

CVOM Charts

CVOM Chart Types

sap.viz.ui5.Line

Pie

sap.viz.ui5.Bar

selectData ( oControlEvent )

Line

Events

Bar

sap.viz.ui5.Pie

Combination

sap.viz.ui5.Combination

CVOM API Reference

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
Country
Country
Country
Country
Country

:
:
:
:
:
:

"Canada", profit: 341.25, revenue:410.87 },


"China", profit: 133.82, revenue:338.29},
"France", profit: 348.76, revenue:487.66 },
"Germany", profit: 217.29, revenue:470.23 },
"India", profit: 117.00, revenue:170.93 },
"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


desired modules.

You can mix such a merged file with the dynamic


on-demand approach: load a big file with the
most common modules and let UI5 load the others
on demand.
Please be aware, that the above tool link creates
the download configuration for the nightly build.

Usage:

Load your application page and


navigate through it (, to load all used
modules)

Press CTRL-ALT-SHIFT-P
(UI5 Technical Info)

Expand the list of loaded modules,


select and copy it

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!