Professional Documents
Culture Documents
SAP UI
1
Agenda
SAPUI5 Overview
Databinding
Runtime Resources
Programming Applications
Extending SAPUI5
Notepad Controls
CVOM Charts
Optimizing SAPUI5
MVC
SAP UI
3
SAPUI5
The short name
UI5
Internal name
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.
Open AJAX compliant and can be used together with/uses other standard
JS libs
Internet
Explorer
Version 9
Version 8
Firefox
Chrome
Safari
Latest version
Latest version
Development track
Release track
UI5 Core
jQuery
jQuery UI
data.js
sap.ui.commons
Includes
sap.ui.ux3
sap.ui.table
sap.ui.dev
Experimental controls
Include their own JavaScript, HTML and CSS into UI5 based pages
This way UI5 development groups should not become a bottleneck for application groups in need of a certain functionality.
Documentation and
Information
UI5 Wiki
Demo kit
API Documentation
SAPUI5 Versions
Test Suite
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
Runtime 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
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:
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
<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
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
Instead of putting the attributes in the script tag, they can also be added as URL parameters
<!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.
sap.ui.getCore()
sap.ui.getCore().byId(id)
sap.ui.getCore().applyChanges()
jQuery.sap.domById(id)
jQuery.sap.byId(id)
Exercise getCore().byId()
Instantiate a MatrixLayout
new sap.ui.commons.layout.MatrixLayout
new sap.ui.commons.TextField
new sap.ui.commons.Button
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>
Overview
SAPUI5 Developer Studio is a set of tools for Eclipse that greatly simplify the development process for
UI5 applications and controls, including:
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.
Click "Next".
Click "Next".
Click "Next".
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});
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.
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>
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");
Exercise - Localization
MVC
JavaScript
sap.ui.core.mvc.JSView
JSON
sap.ui.core.mvc.JSONView
sap.ui.core.mvc.XMLView
Controller
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:
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
onInit
onBeforeRendering
onAfterRendering
onExit
sap.ui.controller("sap.hcm.Address", {
onInit:
function() {},
onBeforeRendering: function() {},
onAfterRendering: function() {},
onExit:
function() {},
myOwnMethod:
});
function() {}
<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>
{
"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
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.
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.
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] );
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);
With the ResourceModel, there is a wrapper for resource bundles that exposes the localized texts as a
model for data binding.
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");
{
company: {
name: "ACME",
info: {
employees: 3
},
contacts: [{
name:
"Barbara",
phone: "873"
},{
name: "Gerry",
phone: "734"
}]
}
}
/company/name
/company/info/employees
/company/contacts
name
info/employees
contacts
name
phone
Property Binding
There are two ways to bind properties to the model, in the constructor with curly braces or using the
bindProperty method.
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.
The aggregation binding can also be defined using the bindAggregation method of a control.
{
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.
When using aggregation binding, you can provide initial sorting and filtering.
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.
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);
}
});
Defines data formats representing resources like collections, entries, etc. in either
Atom or JSON format
http://services.odata.org/OData/OData.svc/Category(1)/Products?
$top=2
Service Root URI
Resource path
Query options
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
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
One can add a CSS class to the top level HTML element of the UI5 control
UI5 Theming
Based on CSS
Every theme uses base theme CSS plus specific theme related
CSS files on top
Optional compression/optimization
Parameters
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 */
[...]
}
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"))
Gold Reflection
Blue Crystal
Ux Target Design:
specification
Extending UI5
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
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
style=\"height:500px;width: 500px\"></div>"
});
/* starts rendering when the placeholder is rendered */
oHTML.attachAfterRendering(
function(oEvent){
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 is available on all Controls (and the base classes) and is used to define
a new subclass.
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
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.
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: {
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:
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
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.
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;
},
// event handler
onclick: function(e) {
alert("Control " + this.getId()
+ " was clicked.");
}
Control Renderer
Example:
renderer:
"sap.ui.commons.ButtonRenderer"
CVOM Charts
sap.viz.ui5.Line
Pie
sap.viz.ui5.Bar
selectData ( oControlEvent )
Line
Events
Bar
sap.viz.ui5.Pie
Combination
sap.viz.ui5.Combination
sap.service.visualization
new sap.ui.model.json.JSONModel();
new sap.ui.table.DataTable();
new sap.service.visualization.dataset.SimpleDMDataset();
new sap.service.visualization.chart.Bar();
Solution to Exercise
var oChartData = [ {
{
{
{
{
{
Country
Country
Country
Country
Country
Country
:
:
:
:
:
:
= 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);
sap-ui-core.js
many requests
sap-ui-core-all.js
less requests
bigger filesize
Usage:
Press CTRL-ALT-SHIFT-P
(UI5 Technical Info)
Thank you!