401
User Interface Add-On 1.0 SPS 06 for SAP NetWeaver Document Version: 1.0 - 2013-11-15 Developer Guide for User Interface Add-On

SAP_UI

Embed Size (px)

DESCRIPTION

sap ui

Citation preview

User Interface Add-On 1.0 SPS 06 for SAP NetWeaverDocument Version: 1.0 - 2013-11-15

Developer Guide for User Interface Add-On

Table of Contents1 Developer Guide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.1 SAPUI5 Developer Guide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.1.1 Getting Started. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.1.2 Concepts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431.1.3 Developing User Interfaces with SAPUI5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591.1.4 References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293

1.2 SAP NetWeaver User Interface Services Developer Guide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3281.2.1 Navigation Using Callable Entities. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3281.2.2 JavaScript Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3321.2.3 OData Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3631.2.4 Cache for OData Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3831.2.5 ABAP APIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3861.2.6 Developing Applications for the Launchpad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396

2 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Table of Contents

1 Developer GuideUI Development Toolkit for HTML5 (SAPUI5)

SAPUI5 is a user interface technology for building and adapting client applications. The SAPUI5 runtime is a client-side HTML5 rendering library with a rich set of UI controls for building both desktop and mobile applications. To support you in developing applications, SAPUI5 tools come with a set of eclipse-based wizards and editors. They provide wizards to create application projects and views according to the Model View Controller concept, and other features like JavaScript code completion and in-place application preview. You can store and run your SAPUI5 applications on SAP NetWeaver Application Server with the help of the SAPUI5 ABAP Repository (depending on your SAP NetWeaver release).

SAP Netweaver User Interface Services

SAP NetWeaver user interface services offers a set of back-end services and front-end services. To decouple your UI, you use OData services for ABAP-based back-end systems based on an OData channel that is part of SAP NetWeaver Gateway. To couple to a new UI technology, you use front-end services.

SAP NetWeaver user interface services are based on the UI development toolkit for HTML5 (SAPUI5):

Related Information

SAPUI5 Developer Guide [page 3]The UI development toolkit for HTML5 (SAPUI5) is a user interface technology that is used to build and adapt client applications.

SAP NetWeaver User Interface Services Developer Guide [page 328]

1.1 SAPUI5 Developer Guide

The UI development toolkit for HTML5 (SAPUI5) is a user interface technology that is used to build and adapt client applications.

The SAPUI5 runtime is a client-side HTML5 rendering library with a rich set of standard and extension controls. It provides a lightweight programming model for desktop as well as mobile applications.

Based on JavaScript, it supports RIA like client-side features. SAPUI5 complies with OpenAjax and can be used together with standard JavaScript libraries.

● It supports CSS3, which allows you to adapt themes to your company's branding in an effective manner.● It is based on an extensibility concept regarding custom controls.● It uses the open source jQuery library as a foundation

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 3

SAPUI5 SDK

The SDK comes together with a Demo Kit, which contains:

● A Developer Guide with a summary of valuable information around the used programming languages, open source technologies, development tools and APIs

● A Controls section containing running demo examples with descriptions and source codes● API Reference with JavaScript documentation of Framework and Control API● Test Suite which shows all controls running with different property settings where you can interactively adapt

the controls you use for your test purpose.

The Demo Kit is part of the installation, you can find it on your server using the following path: http://<host>:<port>/sap/public/bc/ui5_ui5/demokit/

Note

You can also access the Demo Kit online: SAPUI5 Demo Kit on SAP HANA Cloud

This might not be the version of your local installation.

Related Information

Getting Started [page 4]Here you find information on how to adjust your enviroment and to get started with some easy examples including an introduction to the SAPUI5 tools.

Concepts [page 43]Overview on the architecture and concepts of SAPUI5

Developing User Interfaces with SAPUI5 [page 59]

1.1.1 Getting Started

Here you find information on how to adjust your enviroment and to get started with some easy examples including an introduction to the SAPUI5 tools.

Prerequisites

You've installed the SAPUI5 runtime and tools.

If not already done so, refer to SAP note 1747308 on installation of SAPUI5.

4 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Choose your browser

Before you really get started, check the list of supported browsers to choose one that fits your needs.

Browser Support: SAPUI5 for Desktop [page 6]

Browser Support: SAPUI5 for Mobile [page 12]

Creating SAPUI5 applications

To get started with SAPUI5, you have two different options: Either you just create an HTML page (even with notepad, if you want to) or you start directly using the SAPUI5 tools in Eclipse.

Creating Simple SAPUI5 Applications

The easiest way to work with SAPUI5 is to include a set of JavaScript libraries into your HTML page. After that you can use all controls provided by these libraries to construct one or more control trees and include them into your HTML page. The framework also supports the JavaScript Object Notation (JSON) to initialize controls with a reduced typing effort.

Create Your First SAPUI5 Application [page 19]

Creating Mobile Apps with SAPUI5

SAPUI5 provides an additional control library called sap.m, which is optimized for mobile devices.

Create your First Mobile App using SAPUI5 [page 14]

Create Applications using SAPUI5 tools

Using the SAPUI5 application tools in Eclipse allows you to create sophisticated SAPUI5 application projects based on the Model View Controller concept. The tools provide additional features such as SAPUI5 Snippets or JavaScript Templates.They provide wizards to create SAPUI5 applications for desktop as well as for mobile devices.

Develop Your First Application using SAPUI5 Tools [page 23]

Testing your SAPUI5 applications

There are different options to test your applications:

● Test Your SAPUI5 Application on an ABAP Server [page 42]● Testing SAPUI5 Applications in Eclipse [page 278]

1.1.1.1 Choose Your Browser

You need to check which browser suits best to your use case.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 5

Supported Browsers

For displaying Mobile apps for testing purposes locally on your Desktop computer, you need a WebKit based browser such as Google Chrome.

Related Information

Browser Support: SAPUI5 for Desktop [page 6]The UI development toolkit for HTML5 (SAPUI5) is a control library based on CSS3, HTML5 and the new JavaScript API. That's why only browsers with HTML5 capabilities are supported.

Browser Support: SAPUI5 for Mobile [page 12]

1.1.1.1.1 Browser Support: SAPUI5 for Desktop

The UI development toolkit for HTML5 (SAPUI5) is a control library based on CSS3, HTML5 and the new JavaScript API. That's why only browsers with HTML5 capabilities are supported.

Browser Support for Core and Standard Libraries

Note

Also refer to SAP note 1716423

Supported Browsers

The following browsers are supported for Microsoft Windows platforms only:

● Microsoft Internet Explorer 9 and upwards, so including Microsoft Internet Explorer 10● Mozilla Firefox 17 (aka Firefox Extended Support Release - ESR) and latest version● Google Chrome latest version

The following browser is only supported for MAC OS X:

● Safari 5.1 and upwards

6 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Browsers with Restricted Support

Internet Explorer 8 (IE8): There are degradations in visual design and over time also restricted functionality.

For more information, see

● Degradations by Feature.● Degradations by Control [page 9]

Not supported Browsers

Internet Explorer 6 and 7 are not supported. All browsers not mentioned above are also not supported.

Browser Support for VIZ Charting

The VIZ charting library (sap.viz) relies on the open source component D3 which in turn relies on the availability of Scalable Vector Graphics (SVG). As SVG is not supported by IE8 and not fully supported by FF ESR, the VIZ charting library is also not supported on those browsers.

Degradations by Feature

The following sections describe the degradations for older Browser versions, such as FireFox 3.6 or Internet Explorer 8 (IE8).

Rounded Corners

IE8 and lower versions of IE do not support the CSS property border-radius. As a result, controls in themes that use this property have square corners instead of rounded corners.

In the UX theme this affects the following controls:

● Button● ComboBox● DatePicker and its popup● DropdownBox● ListBox● MessageBar● Panel● ProgressIndicator

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 7

● TextArea● TextField

Button in FireFox 3.6 Button in Internet Explorer 8

Box Shadow

IE 8 and lower versions of IE do not support the CSS property box-shadow. As a result, controls in themes that use this property do not have a shadow. This property is usually used to enhance a 3D effect, for example, along vertical edges or to drop a shadow for a box "floating" above other content, which is used for all kinds of popup windows.

In the UX theme, this affects the following controls:

● Button(3D)● ComboBox(Popup)● DatePicker(Popup)● DropdownBox(Popup)● Menu(Popup)● MenuButton(Popup)● MessageBar(+Popup)● ProgressIndicator(3D)● RichTooltip● TextArea(3D)● TextField(3D)● Toolbar(OverflowMenu)

ComboBox in FireFox 3.6 ComboBox in Internet Explorer 8

Background Size

IE 8 and lower versions of IE do not support the property background-size which allows to stretch a background image or gradient.

This affects the Button control.

8 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Button in FireFox 3.6 Button in Internet Explorer 8

Gradient Backgrounds

IE8 only supports gradients in a limited way, so some gradients may be missing.

This affects tables. In the example, compare the table header and row selectors.

Gradient Background in FireFox 3.6 Gradient Background in Internet Explorer 8

Native Scrollbars

For native scrollbars, see the ComboBox example in the Box Shadow section.

Degradations by Control

The following table gives an overview of degradations.

Control Corners Shadow BG Size Gradients Scrollbars Degradation in IE8

Accordion

Button X X X No rounded corners, vertical edges without 3D effect and background has no scale when button size differs from default height

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 9

Control Corners Shadow BG Size Gradients Scrollbars Degradation in IE8

CheckBox

ComboBox X X X No rounded corners, no 3D effect for vertical edges and popup has no shadow

DatePicker X X X No rounded corners, no 3D effect for vertical edges and popup has no shadow

Dialog X Native scrollbars

DropdownBox X X X No rounded corners, no 3D effect for vertical edges and popup has no shadow

FileUploader X X Inherited from the components used (InputField and Button)

HorizontalDivider

Image

Label

Link

ListBox X X X No rounded corners, no 3D effect for vertical edges

Menu X Popup without shadow

MenuButton X X X No rounded corners, vertical edges without 3D effect, background does not scale when button size differs from

10 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Control Corners Shadow BG Size Gradients Scrollbars Degradation in IE8

default height, popup without shadow

MenuBar X Menu items without rounded corners

MessageBar X X No rounded corners, no shadow, message list popup without shadow

MessageBox

Panel X Native scrollbars

ProgressIndicator

X X No rounded corners, vertical edges without 3D effect

RadioButton

RichTooltip X X No shadow; if it had a shadow, the shadow would not have rounded corners

Slider

Splitter

Table X X Native scrollbars, headers/line markers only show 2-colors instead of gradient

TextArea X X X No rounded corners, vertical edges without 3D effect

TextField X X No rounded corners, vertical edges without 3D effect

TextView

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 11

Control Corners Shadow BG Size Gradients Scrollbars Degradation in IE8

Toolbar X Overflow menu without shadow

1.1.1.1.2 Browser Support: SAPUI5 for Mobile

The following tables give an overview of the platforms supported by the sap.m library of SAPUI5 for Mobile. Depending on the theme you use - SAP Mobile Visual Identity or SAP Blue Crystal - different platforms and browsers are supported.

iOS

iOs is supported as of platform version 5.

Browser Safari Web View

Supported with SAP Blue Crystal Yes Yes

Supported with SAP Mobile Visual Identity

Yes (iOS5 and iOS6) Yes (iOS5 and iOS6)

Chrome and Opera are not supported. When using SAP Mobile Visual Identity, iOS7 is not supported

Android

Android is supported as of platform version 2.3

Browser Android Browser Chrome Web View

Supported with theme:

SAP Blue Crystal Yes Yes Yes

SAP Mobile Visual Identity Yes Yes Yes

Opera, Opera mini and Firefox are not supported on Android devices.

BlackBerry

Blackberry is supported as of platform version 10.

NoteThe sap.makit library supports the same platforms as Mobile Visual Identity theme excluding BlackBerry 10.

12 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Browser BlackBerry Browser Web View

Supported for both themes Yes Yes

Theme style when using SAP Mobile visual Identity

Android Android

Opera Mini is not supported on BlackBerry devices.

Windows Mobile

Windows Mobile is not supported.

Windows Desktop

When using Windows running on a desktop device, there is no touch support.

Browser Internet Explorer FireFox Chrome

Supported versions 9 or higher latest and Extended Support Release

latest version

Safari and Opera are not supported.

SAPUI5 for Mobile is not supported on the desktop for SAP Mobile Visual Identity. Only for development scenarios you can use it with Safari and Google Chrome, with either Android or iOS style, depending on your configuration.

Mac OS

On Mac OS, Safari browser is supported in version 5.1 or higher when using SAP Blue Crystal theme.

SAP Mobile Visual Identity is not supported, you can use it only for development scenarios, also with Safari browser.

Exceptions

Note● SAP Mobile Visual Identity is only supported for the following controls: ActionSheet, ActionListItem, App,

BusyDialog, BusyIndication, Button, CheckBox, Carousel, CustomListItem, DateTimeInput, Dialog, DisplayListItem, FlexBox, GrowingList, Input, Image, InputListItem, Label, List, NavContainer, MessageToast, Page, Bar, Popover, PullToRefresh, RadioButton, SegmentedButton, StandardListItem, ScrollContainer, SearchField, Select, Slider, Switch, SplitApp, Text, TextArea

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 13

● The control FlexBox is not supported in Internet Explorer 9.● The control Carousel is not supported in Internet Explorer.

1.1.1.2 Create your First Mobile App using SAPUI5

Whether you develop a SAPUI5 application for desktop or for mobile, the concepts are very similar. SAPUI5 provides an additional control library called sap.m, which is optimized for mobile devices.

The sap.m library provides a mobile-style theme, which makes users feel comfortable on both, Android and Apple devices. It has a focus on touch interactions.

NoteThe sap.m mobile library is optimized for mobile browsers based on WebKit. Currently, the library does not run properly on other browsers, such as Microsoft Internet Explorer and Mozilla Firefox. Therefore we recommend to use Google Chrome or Apple Safari for tests on desktop PCs.

Also, the mobile library only uses touch events and deduces its appearance from the platform it is running on. For tests with Chrome or Safari on desktop PCs, you therefore need the to set one of the following URL parameters:

● sap-ui-xx-fakeOS=android● sap-ui-xx-fakeOS=ios● sap-ui-xx-fakeOS=blackberry ● sap-ui-xx-fakeOS=winphone

The URL parameter suggests to emulate touch events from mouse events and to apply the styles for either Android, iOS, BlackBerry of Windows Phone. You can also add this parameter as data-sap-ui-xx-fakeOS attribute to the bootstrap script tag.

Related Information

Create a HTML Page for Your Mobile App [page 15]You first create a HTML page and define the meta tags, a script tag to load the SAPUI5 libraries and a placeholder for your mobile app.

Initialize the Mobile App [page 15]The sap.m library provides a control called App which is meant to be the root control of a mobile application. It provides the initialization of the HTML page, sets some meta tags to ensure an as-native-as-possible look&feel, and can manage different pages and the animations between them.

Add Content Pages [page 16]Typical mobile applications are often composed of a number of pages/views/screens between which the user can navigate. You now add two of them to your app.

Run Your First Mobile App [page 17]To test a mobile app on your desktop, you have to ensure some prerequisites.

14 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.1.2.1 Create a HTML Page for Your Mobile AppYou first create a HTML page and define the meta tags, a script tag to load the SAPUI5 libraries and a placeholder for your mobile app.

1. Create a HTML page called mobile.html2. Add the HTML5 doctype definition: <!DOCTYPE html>" in the first line and the Internet Explorer-specific

meta tag :<meta http-equiv="X-UA-Compatible" content="IE=edge" />" are the beginning of <head> element.

This ensures that all browsers use the latest version of their rendering engine. Although Microsoft Internet Explorer is not really used widely on mobile devices and not yet supported by the SAPUI5 mobile library, this meta tag makes the page more future-proof.

3. Add a second meta tag: <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>.

This lets all browsers treat the file as UTF-8 encoded (assuming that you use this encoding when editing/saving the file)

4. Add a <div> element to <body>.

5. The "sapUiBody" class should always be added to the <body> tag to initialize font and colors for the whole page:

<body class="sapUiBody"> <!-- This is where the App will live: --> <div id="content"></div></body>

6. To load the SAPUI5 JavaScript file, that contains the library, add the following script tag in the <head>:

<script src= "http://<http://<server>:<port>/sapui5/resources/sap-ui-core.js" id= "sap-ui-bootstrap" data-sap-ui-libs= "sap.m" data-sap-ui-theme= "sap_mvi"> </script>

Note that you are only loading the "sap.m" control library and the "sap_mvi" theme. mvi stands for Mobile Visual Identity and is the name of the SAP Mobile design.

7. Replace <server> and <port> with your local SAPUI5 installation or point to the SAPUI5 libraries on SAP HANA Cloud Platform: https://sapui5.hana.ondemand.com/resources/sap-ui-core.js

At this point, SAPUI5 including the mobile controls is loaded and ready to use.

Initialize the Mobile App [page 15]

1.1.1.2.2 Initialize the Mobile AppThe sap.m library provides a control called App which is meant to be the root control of a mobile application. It provides the initialization of the HTML page, sets some meta tags to ensure an as-native-as-possible look&feel, and can manage different pages and the animations between them.

Create the control and define the page that you want to display first:

// create a mobile App // it initializes the HTML page for mobile use and provides animated page

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 15

handling var app = new sap.m.App("myApp", {initialPage:"page1"}); // page1 should be displayed first

○ Instead of using the App control, you can also use jQuery.sap.initMobile() to set up the HTML and use other full screen controls, such as sap.m.Page or sap.m.Carousel as root element of your app.

1.1.1.2.3 Add Content Pages

Typical mobile applications are often composed of a number of pages/views/screens between which the user can navigate. You now add two of them to your app.

1. One sap.m.Page control is created, its title is set and the content is just one button:

// create the first page of your applicationvar page1 = new sap.m.Page("page1", { title: "Initial Page", content : new sap.m.Button({ // content is just one Button text : "Go to Page 2", tap : function() { app.to("page2"); // when tapped, it triggers drilldown to page 2 } })});

When the Button is pressed, it triggers a drilldown navigation by calling app.to("page2"), where page2 is the ID of the second page. You could also give the animation type. The default is a slide animation from right to left.

sap.m.Page controls can be used as pages, and the aggregation is called pages, but other controls could be used as well.

2. Add the following to the <script> seciton of the HTML page below the part, where you've initialized the app:

// create the second page of your applicationvar page2 = new sap.m.Page("page2", { title: "Page 2", showNavButton: true, // page 2 should display a back button navButtonTap: function(){ app.back(); // when tapped, the back button should navigate back up to page 1 }, icon: "http://www.sap.com/global/ui/images/global/sap-logo.png", content : new sap.m.Text({text:"Hello Mobile World!"})});

showNavButton is set to true to get a Back button displayed. When this button is triggered, the handler calls app.back(). This causes an inverse animation, which leads back to the main page.

A header icon, which is only visible on Android, and "Hello Mobile World" content is also given.3. Finally, add the two pages to the App:

// add both pages to the Appapp.addPage(page1).addPage(page2);

16 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The app is placed into the HTML like a SAPUI5 desktop control. The App takes care to cover the whole screen.

Run Your First Mobile App [page 17]

1.1.1.2.4 Run Your First Mobile App

To test a mobile app on your desktop, you have to ensure some prerequisites.

Your operating system is Microsoft Windows and you use a current WebKit-based browser (Google Chrome or Apple Safari). Other operating systems work as well, but the procedure may differ. Also, the mobile library is currently not optimized for Mozilla Firefox and Microsoft Internet Explorer.

NoteThe URL in the script tag is pre-filled as https://sapui5.hana.ondemand.com/resources/sap-ui-core.js. This is the URL where the resources are located in the SAP HANA Cloud delivery. Test this URL first and if it does not work, replace this URL with the location of SAPUI5 on your local server.

Also note that the version of SAPUI5 deployed on https://sapui5.hana.ondemand.com/ may be updated with a delay of some days or weeks after a new release of SAPUI5, even though we try to keep them in sync. This example will work nevertheless.

1. Right-click on your desktop and choose New Text Document .2. Enter a name for the new file, for example "mobile.html", and confirm the extension change warning.3. Right-click on the new file and choose Edit. Make sure it opens in Notepad and not in MS Word.4. Copy and paste the HTML code below and save the file. Keep in mind that the SAPUI5 URL may need to be

adapted.5. Drag and drop the file into the browser window.6. To load the example on a mobile device, you put the file on a server.7. To play around with the app in your desktop browser, add the following URL parameter to the file URL: sap-

ui-xx-fakeOS=ios, so that the URL reads : "mobile.html?sap-ui-xx-fakeOS=ios". This enables the simulation of touch events on desktop PCs. This also enables the iPhone/iPad styling; if you want to see the Android styling, use sap-ui-xx-fakeOS=android instead.

<!DOCTYPE HTML><html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>Mobile App in 23 Seconds Example</title> <script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-libs="sap.m" data-sap-ui-theme="sap_mvi"> </script> <!-- only load the mobile lib "sap.m" and the "sap_mvi" theme --> <script> // create a mobile App // it initializes the HTML page for mobile use and provides animated page handling var app = new sap.m.App("myApp", {initialPage:"page1"}); // page1 should be displayed first // create the first page of your application

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 17

var page1 = new sap.m.Page("page1", { title: "Initial Page", content : new sap.m.Button({ // content is just one Button text : "Go to Page 2", tap : function() { app.to("page2"); // when tapped, it triggers drilldown to page 2 } }) }); // create the second page of your application var page2 = new sap.m.Page("page2", { title: "Page 2", showNavButton: true, // page 2 should display a back button navButtonTap: function(){ // when tapped, the back button should navigate back up to page 1 app.back(); }, icon: "http://www.sap.com/global/ui/images/global/sap-logo.png", content : new sap.m.Text({text:"Hello Mobile World!"}) }); app.addPage(page1).addPage(page2); // add both pages to the App // place the App into the HTML document app.placeAt("content"); </script> </head> <body class="sapUiBody"> <div id="content"></div> </body></html>

You should now see the following mobile App on iOS:

And the following mobile App on Android:

18 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

If you have set the sap-ui-xx-fakeOS URL parameter, you can navigate to the second page by clicking the button.

To open the application on a real mobile device, you can also put the HTML document on a Web server and load the resulting URL in your mobile browser.

1.1.1.3 Create Your First SAPUI5 Application

You can include a bootstrap to the SAPUI5 JavaScript libraries to use SAPUI5 in an HTML page without having set up the SAPUI5 application development tools in Eclipse.

This page explains how to create and run a simple SAPUI5 application from scratch within twenty seconds (with some practice… the current record is 16 seconds).

If you are interested in exactly doing this without reading too much, you can skip the background information and read the And how to do it in 20 Seconds section below.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 19

Background Information

As SAPUI5 is a client-side web UI library meaning that it runs in a browser, a SAPUI5 application typically is composed of an HTML page and, if required, many more files.

SAPUI5 is implemented in JavaScript. For loading SAPUI5, its bootstrap needs to be included with a <script> tag. The last two attributes select the visual design to apply initially (other choices would be sap_hcb or sap_platinum) and the SAPUI5 control library/libraries to use (sap.ui.dev would be another one). In your scenario you need to make sure the URL points to a SAPUI5 installation.

<script id="sap-ui-bootstrap" src="resources/sap-ui-core.js" data-sap-ui-theme="sap_goldreflection" data-sap-ui-libs="sap.ui.commons"></script>

SAPUI5 UI elements are created and modified programmatically:

// create the button instancevar myButton = new sap.ui.commons.Button("btn");

// set properties, e.g. the text (there is also a shorter way of setting several properties)myButton.setText("Hello World!");

// attach an action to the button's "press" event (use jQuery to fade out the button)myButton.attachPress(function(){$("#btn").fadeOut()});

There is also a shorthand notation based on JSON for setting multiple properties; you could also write:

var myButton = new sap.ui.commons.Button({text:"Hello World!",tooltip:"Hello Tooltip!"});

Finally you need to tell SAPUI5 where the UI control should be placed. You can just give the ID of an element in the page to do so:

// place the button into the HTML element defined belowmyButton.placeAt("uiArea");

This element must exist somewhere in the HTML page, so you need to put the following code to the desired place within the <body>:

<div id="uiArea"</div>

Currently, you can only put one SAPUI5 control into a parent; for adding more SAPUI5 controls you need to either define more parents, or use a SAPUI5 layout control which can arrange many children.

An alternative way to create and initialize the control in a more jQuery-style manner is also available:

$(function(){ $("#uiArea").sapui("Button", "btn", { text:"Hello World!", press:function(){$("#btn").fadeOut();} }); });

20 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

As a minor detail, the <body> should have a certain CSS class, so the page background and some other styles are properly set:

<body class="sapUiBody">

There are two meta tags at the beginning of the <head>: The first meta tag is used to ensure that Internet Explorer 8+ uses its most standard-compliant rendering mode. The second meta tag is used to let all browsers treat the file as UTF-8 encoded (assuming that you use this encoding when editing/saving the file):

<meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>

And How to do it in 20 Seconds

Assumption for these instructions to work exactly as described: You have a Windows Computer (other OS will work similarly), Internet Explorer 9+ with security option set to Access data across domains for the respective zone, FireFox 13+, Safari 5+ or Chrome 20+, and you know where you can refer to SAPUI5 on some server.

NoteThe URL in the script tag is pre-filled as https://sapui5.hana.ondemand.com/resources/sap-ui-core.js. This is the URL where the resources are located in the SAP HANA Cloud Platform delivery. Test this URL first and if it does not work, replace this URL with the location of SAPUI5 on your local server.

Also note that the version of SAPUI5 deployed on https://sapui5.hana.ondemand.com/ may be updated with a delay of some days or weeks after a new release of SAPUI5. This example will work nevertheless.

Proceed as follows:

1. Right click your desktop and select New Text Document .2. Name the new file, for example "ui5.html", and accept the extension change warning.3. Right click the new file and select Edit. Make sure that the file opens in Notepad and not in MS Word.4. Copy and paste the below HTML code. Keep in mind to adapt the SAPUI5 URL5. Drag the file to the browser window.6. That was it.

<!DOCTYPE html><html><head> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>SAPUI5 in 20 Seconds</title>

<!-- 1.) Load SAPUI5 (from a remote server), select theme and control library --> <script id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" data-sap-ui-theme="sap_goldreflection" data-sap-ui-libs="sap.ui.commons"></script>

<!-- 2.) Create a UI5 button and place it onto the page --> <script> // create the button instance var myButton = new sap.ui.commons.Button("btn");

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 21

// set properties, e.g. the text (there is also a shorter way of setting several properties) myButton.setText("Hello World!");

// attach an action to the button's "press" event (use jQuery to fade out the button) myButton.attachPress(function(){$("#btn").fadeOut()});

// place the button into the HTML element defined below myButton.placeAt("uiArea");

// an alternative, more jQuery-like notation for the same is: /* $(function(){ $("#uiArea").sapui("Button", "btn", { text:"Hello World!", press:function(){$("#btn").fadeOut();} }); }); */ </script>

</head><body class="sapUiBody">

<!-- This is where you place the UI5 button --> <div id="uiArea"></div></body></html>

Result

If you followed the steps above you should now see a button like this which fades out when clicked:

Next Steps

You can now do the following:

● Add more buttons.● Let them do trickier things.● Use a different visual theme as mentioned above, for example sap_ux● Find out about further properties and events of button controls and use those.

22 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● Find out about further controls and add those. For more information, see the Controls Gallery in the Demo Kit.

1.1.1.4 Develop Your First Application using SAPUI5 Tools

The SAPUI5 application development tools in Eclipse support you in developing web applications according to the Model View Controller concept (MVC).

The SAPUI5 application development tools for Eclipse provide wizards to support you in creating SAPUI5 applications in an easy way. With the SAPUI5 application project wizard, the necessary application skeleton containing view(s) and controller will automatically be created.

Creating SAPUI5 applications

The SAPUI5 tools support you in creating applications according to MVC. In this section we guide you through a simple example. You will create a SAPUI5 application project, which includes a control, a method in the controller and an additional view.

More Information

Create an SAPUI5 Application Project [page 24]

Add a Control to Your View [page 27]

Implement a Method in the Controller [page 28]

Utilities

With Eclipse you can make use of utilities for JavaScript development. Additionally SAPUI5 provides templates and snippets.

● JavaScript Code CompletionThe Eclipse JavaScript Development Tools (JSDT) provide an editor which parses scripts and offers code completion functionality. The core libraries for the code completion are made available automatically.

NoteIf your Eclipse installation contains the org.eclipse.wst.jsdt.feature feature in Version 1.3.1, we recommend to update it. Invoking the JavaScript code completion in version 1.3.1 may cause Eclipse to crash.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 23

More Information

JavaScript Code Completion [page 31]

Use JavaScript Templates [page 34]

SAPUI5 Snippets [page 35]

1.1.1.4.1 Create an SAPUI5 Application Project

To create a SAPUI5 Application Project, you must have installed the SAPUI5 Application Development feature in your Eclipse installation.

1. Start the New SAPUI5 Application Project wizard in the Eclipse by choosing New Other ... SAPUI5 Application Development Application Project .

24 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

2. Enter the following project-related data:

○ Project name○ Location (optional, prefilled from the current workspace)○ Target device: 'Desktop' or 'Mobile'○ Select Create an Inital View

Views can also be added later using the SAPUI5 Application View wizard

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 25

3. Enter the following view-related data:

○ Choose the folder in which the view shall be created○ Enter a unique name for your view○ Choose the Development Paradigm.

After finishing the wizard, the system performs the following steps:

● A new dynamic web project is created. All relevant files are created in the WebContent folder.● A prefilled index.html is created which contains sap.ui.commons lib and sap_goldreflection theme in

the boostrap in case of a desktop target device and the sap.m lib and sap_mvi theme in case of mobile target device.

● In WEB-INF folder a web.xml file is created which contains settings for resource handling and the use of SimpleProxyServlet.

● The installed SAPUI5 UI lib plugins are automatically added to the Java build path and added to the deployment assembly.

● The SAPUI5 class path container (if available) is automatically added to the JavaScript include path.● The index.html page is opened in the standard editor.● Inside the JavaScript block of index.html, code completion is available, see JavaScript Code Completion.● An automatic switch to the J2EE perspective is performed.

26 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● If you have selected the Create an Initial View option on the first page of the SAPUI5 Application Project wizard, a view and a view controller are created and the coding to call the view is added to the index.html file.

Add a Control to Your View [page 27]

Implement a Method in the Controller [page 28]

Create an Additional View [page 28]

Integrate a New View [page 31]

Related Information

JavaScript Code Completion [page 31]When using the SAPUI5 tools, code completion is enabled automatically, without the tools, you need to enable it.

Use JavaScript Templates [page 34]You can add SAPUI5 control-specific templates for JavaScript code. Such templates are available, for example, in JavaScript views of SAPUI5 application tools development.

SAPUI5 Snippets [page 35]

Linking your Eclipse Editor to the Demo Kit [page 33]You can use Quick Fixes to display the API documentation of a SAPUI5 control in the Demo Kit.

1.1.1.4.2 Add a Control to Your View

In your SAPUI5 application project, the first step to build your application is to add a control to your view and implement a method to react on user interaction. In this case you create a button and implement a function to react when the user presses it.

To add a control to your view, add the following coding depending on the type of your view:

○ In a JS view add the following to the createContent function

var aControls = []; var oButton = new sap.ui.commons.Button({ id : this.createId("MyButton"), text : "Hello JS View" }); aControls.push(oButton.attachPress(oController.doIt)); return aControls;

○ In an HTML view add the following to the template tag:

<div data-sap-ui-type="sap.ui.commons.Button" id="MyButton" data-text="Hello HTML View" data-press="doIt"></div>

○ In an XML view add the following coding to the core tag

<Button id="MyButton" text="Hello XML View" press="doIt"/>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 27

○ In a JSON view add the following to the content function

"Type":"sap.ui.commons.Button", "id":"MyButton", "text":"Hello JSON View", "press":"doIt"

A button is added to your view with an event that is triggered when the user presses it.

The doIt method, which is called in each of these view types, is implemented in the controller:

Implement a Method in the Controller [page 28]

1.1.1.4.3 Implement a Method in the Controller

All functions that are not directly related to the user interface should be handled in the controller to ensure clear separation between UI and data. In this case you add a method to handle the event, which is attached to a button.

You've created a button as described in: Add a Control to Your View [page 27]

To handle this event, add the following function to the controller:

doIt : function(oEvent) { alert(oEvent.getSource().getId() + " does it!"); }

1.1.1.4.4 Create an Additional View

● A SAPUI5 application view can only be created for a SAPUI5 application project that has been created with the SAPUI5 Application Wizard and not for other kinds of projects.

● A SAPUI5 application view name needs to be unique inside the project folder.● The specified folder for a SAPUI5 application view needs to be WebContent/<application name> or a sub

folder.

28 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1. Choose New Other... SAPUI5 Application Development View to open the New SAPUI5 Application

View wizard.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 29

2. Fill in the required data:

○ Select the SAPUI5 application project, in which you want to create the view.○ Select a folder, in which you want to store the view (default is WebContent/<application name>).○ Enter a name for the view.○ Select the development paradigm, see View Types.

When you finish the wizard, the system creates the view in the specified folder. The file name suffix indicates the development paradigm:

● <viewname>.view.js for JavaScript views● <viewname>.view.xml for XML views● <viewname>.view.json for JSON views● <viewname>.view.html for HTML views

If the corresponding index.html file contains sap.m lib in the bootstrap, that is, if the SAPUI5 application project has been created for a mobile target device, the view contains coding for instantiating a mobile page control sap.m.Page.

The system also creates a controller file <viewname>.controller.js with draft coding.

For JavaScript views, code completion is available, see JavaScript Code Completion.

30 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteIf you rename the view or controller file, or move them to a different folder, the coding in the view and controller and in the places where the view is used needs to be adapted manually.

1.1.1.4.5 Integrate a New View

To integrate a new view, you can either add it to index.html or nest it into another view.

If you create a new view for an existing SAPUI5 application project, the view needs to be manually called.

To call a view, choose from the following options:

○ Directly embed the new view in the index.html page○ All Views can be nested independent of the view type. Each view type behaves like any SAPUI5 control.

The viewName property defines, which views are embedded. To nest a view, proceed according to the given examples:

For XML view type:

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml"> <Panel> <core:JSView id="myJSView" viewName="sap.hcm.Bankaccount" /> </Panel><core:View>

For HTML views, the nested view looks as follows:

<template data-controller-name= "example.mvc.test" >

<div data-sap-ui-type= "sap.ui.core.mvc.HTMLView" id= "MyHTMLView" data-view-name= "example.mvc.test2" ></div> <div data-sap-ui-type= "sap.ui.core.mvc.JSView" id= "MyJSView" data-view-name= "example.mvc.test2" ></div> <div data-sap-ui-type= "sap.ui.core.mvc.JSONView" id= "MyJSONView" data-view-name= "example.mvc.test2" ></div> <div data-sap-ui-type= "sap.ui.core.mvc.XMLView" id= "MyXMLView" data-view-name= "example.mvc.test2" ></div>

</template>

1.1.1.4.6 JavaScript Code Completion

When using the SAPUI5 tools, code completion is enabled automatically, without the tools, you need to enable it.

NoteIf your Eclipse installation contains the org.eclipse.wst.jsdt.feature feature in Version 1.3.1, we recommend to update it. Invoking the JavaScript code completion in version 1.3.1 may cause Eclipse to crash.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 31

Automatic Code Completion for SAPUI5 Application Projects

The Eclipse JavaScript Development Tools (JSDT) provide an editor which parses scripts and offers a code completion functionality.

Code Completion for SAPUI5 Views

For JavaScript views, code completion is available.

32 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Enabling Code Completion for Other Projects

If you are not working with a SAPUI5 application project, you can perform the following preparing steps to add the required SAPUI5 core libraries to the JavaScript include path.

Ensure that the JavaScript Facet is set and proceed as follows:

1. Open Project Properties .2. Select Project Facets.3. If you do not see the list of all possible facets, click the link: Convert to facet form and wait a second to see all

available facets.4. Mark JavaScript Facet on the same view.5. Leave the project properties.

Your project now has the JavaScript facet. Now you can add the SAPUI5 core libraries. Proceed as follows:

● Open Project Properties .

● Choose JavaScript Include Path .● Select Add JavaScript Library….● Select SAPUI5.

You should now be able to see the following JavaScript resources in your project:

1.1.1.4.7 Linking your Eclipse Editor to the Demo KitYou can use Quick Fixes to display the API documentation of a SAPUI5 control in the Demo Kit.

1. Place the cursor on the actual SAPUI5 control name in your JavaScript code or in your XMLView. The name of the control in JavaScript code usually starts with sap.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 33

2. To see all available Quick Fixes, press CTRL+1.

3. To open the API documentation of the control in the Demo Kit, choose Display in Demo Kit.

1.1.1.4.8 Use JavaScript Templates

You can add SAPUI5 control-specific templates for JavaScript code. Such templates are available, for example, in JavaScript views of SAPUI5 application tools development.

The templates are an overview over all available

● control properties● aggregations● associations and● events

To use the JavaScript templates, the SAPUI5 application development tools feature has to be installed in your Eclipse.

NoteIf your Eclipse installation contains the feature org.eclipse.wst.jsdt.feature in Version 1.3.1, we recommend to update it. In this version, invoking the JavaScript code completion may cause Eclipse to crash.

1. To insert a template, open the JavaScript editor.2. Start typing the name of the respective control or the name of the alias, for example button.3. Choose CRTL + SPACE and choose the control from the code completion list.

All properties and events are inserted.

34 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.1.4.9 SAPUI5 Snippets

You can add SAPUI5-specific code parts, so called SAPUI5 Snippets. Code snippets are templates and examples on how to use the SAPUI5 runtime and controls and what can be done with them. SAPUI5 snippets are available as prepared HTML pages with no separation between model, view and, controller (MVC) and they are generated during startup of the Eclipse runtime.

Before you can use the SAPUI5 snippets, the SAPUI5 application development tools must be installed in your Eclipse.

To open the Snippets view, proceed as follows:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 35

1. Choose Window Show View Other... .

36 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

2. In the Show View dialog, choose General Snippets and confirm you selection with OK.

3. The Snippet view opens.

To insert a snippet, proceed as follows:

1. Create a SAPUI5 application project, see Creating a SAPUI5 Application Project.2. Open the index.html in the HTML editor.3. Delete all content.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 37

4. To insert the snippet code, double click on the snippet or use drag&drop.

38 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

5. Save the code and run it in the integrated browser.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 39

6. NoteIf you have problems with incorrect rendered pages, open the default external browser.

40 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The page should then be displayed correctly:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 41

1.1.1.5 Test Your SAPUI5 Application on an ABAP Server

To test an SAPUI5 application that you have uploaded to an ABAP system, you can directly launch its public URL in a browser window.

● You have shared a SAPUI5 application via the SAPUI5 team provider with the ABAP system.● You have synchronized the application with the ABAP system.

42 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1. You have the following options to launch a synchronized file, for example the index.html, on the ABAP server:

○ Right click the file in the Project Explorer and choose Run As Run On ABAP Server .

○ Open the file in an editor and from the Eclipse and choose Run As Run On ABAP Server .

The launch option is only available if the file is accessible via URL, for example, if it is in the WebContent folder.The URL of the selected file is opened in a browser window. The URL has the following pattern:

<protocol>://<host name>:<port number>/sap/bc/ui5_ui5/<namespace>/<application name>/index.html?sap-client=<client>&sap-ui-language=<language>&sap-ui-appcache=false

NoteThis URL contains test parameters. Do not use them for productive use.

2. Another option to start your application is to select the SAPUI5 application-specific Internet Communication Framework (ICF) node in transaction SICF under sap/bc/ui5_ui5/<namespace>/<application name>, and choose Test Service from the context menu. This starts your index.html page automatically.

Related Information

Synchronizing with the SAPUI5 Repository [page 194]Testing SAPUI5 Applications in Eclipse [page 278]You have different options to test your applications locally in Eclipse.

1.1.2 Concepts

Overview on the architecture and concepts of SAPUI5

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 43

SAPUI5 is a client UI technology based on JavaScript, CSS and HTML5. SAPUI5 applications run in a browser. Depending on the device, the application is supposed to run on (mobile, tablet or desktop PC), you use different UI libraries.

Servers come into play for deploying your applications, storing the SAPUI5 libraries and to connecting to a data base. Depending on the environment in which SAPUI5 is used, the libraries or your applications are stored on an SAP NetWeaver Application Server or an SAP HANA Cloud platform, for example. To access business data for your application the preferred way is using the OData model through a SAP NetWeaver Gateway.

When a user accesses an SAPUI5 application from his device, a request is sent to the respective server to load the application into the browser. The view accesses the relevant libraries. Usually the model is also instantiated and business data is fetched from the data base.

Model-View-Controller

SAPUI5 uses the model-view-controller (MVC) concept to achieve the following objectives:

● Support development in distributed teams with different source locations● Suggest file structure, naming, and usage patterns● Add capability of UI declaration (in comparison to a programmatic construction)

44 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Related Information

Model-View-Controller (MVC) [page 45]Models [page 46]A model holds the data and provides methods to retrieve the data from the data base and to set and update data.

Views [page 47]

Controllers [page 51]A controller in SAPUI5 is used to separate view logic from model logic. All methods for controlling the data flow should be implemented in a controller.

Data Binding [page 52]Data binding is used to bind two data or information sources together to keep them in sync. If data binding is implemented and defined properly, all changes in one data source are automatically reflected in the other data source.

Resource Handling [page 54]There are two layers in SAPUI5 which are responsible for resource handling and which work completely independent from each other: The client side and the server side.

Libraries [page 54]The basis of SAPUI5 is a set of JavaScript and CSS libraries.

1.1.2.1 Model-View-Controller (MVC)In the model-view-controller concept, the representation of information is separated from the user's interaction:

● The view is responsible for defining and rendering the UI.● The model manages the application data.● The controller reacts to view events and user interaction by modifying view and model.

The purpose of data binding in the UI is to separate the definition of the user interface (view), the data that visualized by the application (model), and the code for the business logic for processing the data (controller). The

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 45

separation has the following advantages: It provides a better readability, maintainability, and extensibility and it allows you to change the view without touching the underlying business logic and to define several views of the same data.

With this pattern, a separation of concerns is achieved that facilitates development and change of parts independently.

Views and controllers often form a 1:1 relationship, but it is also possible to have controllers without UI, these controllers are called application controllers. It is also possible to create views without controllers. From a technical position, a view is a SAPUI5 control and can have or inherit a SAPUI5 model.

View and controller represent reusable units and distributed development is highly supported.

Related Information

Views [page 47]

Models [page 46]A model holds the data and provides methods to retrieve the data from the data base and to set and update data.

Controllers [page 51]A controller in SAPUI5 is used to separate view logic from model logic. All methods for controlling the data flow should be implemented in a controller.

1.1.2.1.1 Models

A model holds the data and provides methods to retrieve the data from the data base and to set and update data.

SAPUI5 provides the following predefined models:

● The JSON model can be used to bind controls to JavaScript object data, which is usually serialized in the JSON format. The JSON model is a client-side model and, therefore, intended for small datasets, which are completely available on the client. The JSON model supports two-way binding.

● The XML model is a client-side model intended for small datasets, which are completely available on the client. The XMLModel does not contain mechanims for server-based paging or loading of deltas

● The Resource model is designed to handle data in resource bundles, mainly to provide texts in different languages.

● The OData model enables binding of controls to data from OData services. The OData model is a server-side model: the dataset is only available on the server and the client only knows the currently visible rows and fields.

The JSON model, XML model, and the resource model are client-side models, meaning that the model data is loaded completely and is available on the client. Operations such as sorting and filtering are executed on the client without further server requests. The OData model is a server-side model and only loads the data requested by the user interface from the server. Any changes in data binding or list operations require a new request to the server.

You can not only define one model for your applications, but define different areas in your application with different models and assign single controls to a model. You can also define nested models, for example, a JSON model defined for the application and an OData model for a table control contained in the application.

46 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

A web application should support several data sources, such as JSON, XML, Atom, or OData. However, the way in which data binding is defined and implemented within the UI controls should be independent of the respective data source. It is also possible to create a custom model implementation for data sources that are not yet covered by the framework or are domain-specific.

API References

● sap.ui.model

● sap.ui.model.json.JSONModel

● sap.ui.model.odata.ODataModel

● sap.ui.model.resource.ResourceModel

● sap.ui.model.xml.XMLModel

Related Information

Binding Modes [page 53]Models and Data Binding [page 78]

1.1.2.1.2 Views

Although XML and JSON notation has been introduced for SAPUI5 UI controls, the model-view-controller concept is also supported to facilitate traditional programmatic UI constructions.

SAPUI5 provides the following predefined view types

● XML view. The user interface is defined in an XML file or string.

NoteThe XMLView type supports a mix of XML and plain HTML.

● JSON view. The user interface is defined in a file or string in JSON format.● JS view. The user interface is constructed in a traditional manner.● HTML view. The user interface is defined in an HTML file or string.

The above mentioned view types are predefined and offered for selection as view options in the application creation wizard. If you use SAPUI5 application development tools, you can also plug in other view types. For defining other or custom view types, you extend the base class sap.ui.core.mvc.View.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 47

API Reference

sap.ui.core.mvc.View

Related Information

JS Views [page 48]XML Views [page 49]JSON Views [page 49]HTML Views [page 50]An HTML View is defined by declarative HTML. Like the declarative support, the HTML view supports embedded HTML.

JS Views

You create a JS (JavaScript) view in the same way as a controller and use the suffix .view.js. for the file. SAPUI5 provides the following two default methods for implementation:

● getControllerName(): Specifies the controller belonging to this viewIf this method is not implemented or returns NULL, the view has no controller.

● createContent(): Called initially once after the controller has been instantiatedThis method is used to create the UI. As the method knows the controller, it can directly attach the event handlers.

sap.ui.jsview("sap.hcm.Address", { // this View file is called Address.view.js getControllerName: function() { return "sap.hcm.Address"; // the Controller lives in Address.controller.js },

createContent: function(oController) { var oButton = new sap.ui.commons.Button({text:"Hello JS View"}); oButton.attachPress(oController.handleButtonClicked); return oButton; }

});

The string in quotes denotes the view name that equals the SAPUI5 module name within the require/declare concept.

48 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

XML Views

The XML view type is defined in an XML file. The file name either ends with .view.xml or as an XML string. The file name and the folder structure together specify the name of the view that equals the SAPUI5 module name within the require/declare concept.

For resources/sap/hcm/Address.view.xml, the view name is sap.hcm.Address. The application uses this view name for displaying an instance of this view. If you define the XML view by means of an XML string, no file or require/declare is needed.

The file looks as follows:

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core"> <Panel> <Image src="http://www.sap.com/global/ui/images/global/sap-logo.png"/> <Button text="Press Me!"/> </Panel><core:View>

Nest the XML tags analogous to the nesting sequence of SAPUI5 controls and add the property values as attributes. For information on more complex views see the following sections.

JSON Views

The JSON view type is defined in a file. The file name has to either end with .view.json or as a JSON string. The file name and the folder structure together specify the name of the view that equals the SAPUI5 module name within the modularization concept.

For the file resources/sap/hcm/Address.view.json, the view name is sap.hcm.Address. The application uses this view name for displaying an instance of this view.

The file looks as follows:

{ "Type":"sap.ui.core.mvc.JSONView", "controllerName":"sap.hcm.Address", "content": [{ "Type":"sap.ui.commons.Image", "id":"MyImage", "src":"http://www.sap.com/global/ui/images/global/sap-logo.png" }, { "Type":"sap.ui.commons.Button", "id":"MyButton", "text":"Press Me"

}]

}

You nest the JSON objects analogous to the nesting of SAPUI5 controls and add the property values as attributes. The syntax is the same as the syntax of a JSON constructor for any control.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 49

NoteYou can use strings, boolean and null in your JSON view.

Aggregation Handling in JSON Views

You add child controls as arrays. This is shown in the example above where an image and a button have been added to the view content aggregation.

HTML Views

An HTML View is defined by declarative HTML. Like the declarative support, the HTML view supports embedded HTML.

The view file ends with view.html, for example myview.view.html.

Example:

<template data-controller-name="example.mvc.test"> Hello <h1>Title</h1> <div>Embedded HTML</div> <div class="test test2 test3" data-sap-ui-type="sap.ui.commons.Panel" id="myPanel"> <div class="test test2 test3" data-sap-ui-type="sap.ui.commons.Button" id="Button1" data-text="Hello World" data-press="doIt"></div> <div data-sap-ui-type="sap.ui.commons.Button" id="Button2" data-text="Hello"></div> <div data-sap-ui-type="sap.ui.core.mvc.HTMLView" id="MyHTMLView" data-view-name="example.mvc.test2"></div> <div data-sap-ui-type="sap.ui.core.mvc.JSView" id="MyJSView" data-view-name="example.mvc.test2"></div> <div data-sap-ui-type="sap.ui.core.mvc.JSONView" id="MyJSONView" data-view-name="example.mvc.test2"></div> <div data-sap-ui-type="sap.ui.core.mvc.XMLView" id="MyXMLView" data-view-name="example.mvc.test2"></div> </div></template>

All view specific properties can be added to the <template> tag as data-* attributes.

Related Information

Declarative Support [page 123]

50 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.2.1.3 Controllers

A controller in SAPUI5 is used to separate view logic from model logic. All methods for controlling the data flow should be implemented in a controller.

Controller Definition

You define a simple controller without functions as follows:

sap.ui.controller("sap.hcm.Address", { // controller logic goes here});

The string in quotes specifies the controller name. The controller file is then named Address.controller.js.

NoteThe suffix .controller.js is mandatory for controllers.

Lifecycle Hooks

SAPUI5 provides predefined lifecycle hooks for implementation. You can add event handlers or other functions to the controller and the controller can fire events, for which other controllers or entities can register.

SAPUI5 provides the following lifecycle hooks:

● onInit(): Called when a view is instantiated and its controls (if available) have already been created; used to modify the view before it is displayed to bind event handlers and do other one-time initialization

● onExit(): Called when the view is destroyed; used to free resources and finalize activities● onAfterRendering(): Called when the view has been rendered and, therefore, its HTML is part of the

document; used to do post-rendering manipulations of the HTML. SAPUI5 controls get this hook after being rendered.

● onBeforeRendering(): Invoked before the controller view is re-rendered and not before the first rendering; use onInit() for invoking the hook before the first rendering

NoteFor controllers without a view, no lifecycle hooks are called.

sap.ui.controller("sap.hcm.Address", { onInit: function() { this.counter = 0; }});

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 51

Event Handlers and Other Functions

In addition to lifecycle hooks, a controller can define additional methods that serve as event handlers or additional functionality offered by the controller.

sap.ui.controller("sap.hcm.Address", { increaseCounter: function() { this.counter++; }});

API Reference

sap.ui.core.mvc.Controller

1.1.2.1.4 Data Binding

Data binding is used to bind two data or information sources together to keep them in sync. If data binding is implemented and defined properly, all changes in one data source are automatically reflected in the other data source.

To achieve this, there is a model and a data binding. The model instance holds the data and provides methods to set the data or to retrieve data from a server. It also provides a method for creating bindings to the data. When this method is called, a data binding instance is created, which contains the binding information and provides an event, which is fired whenever the bound data is changed. An element can listen to this event and update its visualization according to the new data.

Usually, the UI uses data binding to bind UI controls to the model, which holds the application data, so that the controls are updated automatically whenever application data is changed. The data binding is also used when changes in the control cause updates in the underlying application data, such as data being entered by a user. This is called two-way binding.

The default binding mode for model implementations (if not implemented otherwise) is two-way binding and the supported binding modes by the model are one-way binding, two-way binding and one-time binding. The default binding mode can be changed by the application for each model instance. A model implementation should specify its supported binding modes and set the default binding mode accordingly (e.g. if the model supports only one way binding the default binding mode should also be set to one way).

Related Information

Binding Modes [page 53]Models and Data Binding [page 78]

52 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Binding Modes

A model implementation supports different binding modes. The following binding modes are available:

● One Way: One-way binding means a binding from the model to the view; value changes in the model update all corresponding bindings and the view

● Two Way: Two-way binding means a binding from the model to the view and from the view to the model; value changes in the model and in the view update all corresponding bindings and the view and model, respectively

● One Time: One-time binding means from model to view once.

The models support different binding modes, The JSON model and the XML model support one-way, two-way data binding, and one-time binding modes, whereas the OData model currently supports one-way binding and one-time binding. The resource model only supports the one-time binding mode because it deals with static texts only.

The following table shows, which binding modes the respective binding models support:

Model One-way Two-way One-time

Resource model -- -- X

JSON model X X X

XML model X X X

OData model X -- X

Default Binding Mode of Models

When a model instance is created, the instance has a default binding mode. All bindings of this model instance have this binding mode as their default.

The following table shows the supported binding modes and their default binding mode for each model implementation.

Model Default binding mode

Resource model One-time

JSON model Two-way

XML model Two-way

OData model One-way

API Reference

sap.ui.model.BindingMode

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 53

1.1.2.2 Resource Handling

There are two layers in SAPUI5 which are responsible for resource handling and which work completely independent from each other: The client side and the server side.

The resource handling of SAPUI5 is separated in two parts - a client-side and a server-side resource handling.

Server-side Resource Handling

SAPUI5 provides resource handlers for different servers. The main purpose of the server-side resource handlers is to provide access to the SAPUI5 libraries. It improves the interaction between client and server, for example in providing a server-side locale fallback for the language, which helps to avoid multiple requests to get the correct language. It is also used to support modularized development of SAPUI5 applications and libraries.The Java resource handler is aligned with the concept of the JavaServer Faces.

Client-side Resource Handling

On the client-side SAPUI5 provides the following mechanisms to manage resources:

● It supports localization of application texts with resource bundles.● It allows to modularize the JavaScript files.

Both concepts are loading additional resources from a server where this server might be any kind of web server. It does not depend on any server side technology.

Related Information

Modularization and Resource Handling [page 152]

1.1.2.3 Libraries

The basis of SAPUI5 is a set of JavaScript and CSS libraries.

To use these libraries, different ways to embed them into your application are provided and this is handled automatically by the respective resource handler. You can use different libraries in one application.

The mobile library, called sap.m, ist designed especially for mobile devices and tablets, but can be used for desktop applications as well. The other libraries are designed for desktop applications and can be used to run on tablets as well, but not focussed on mobile devices.

54 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Table 1: Main UI LibrariesLibrary

Description Supported Devices API References

Mobile Tablet Desktop

sap.ui.commons

Common library for standard controls

-- Yes Yes sap.ui.commons

sap.m

Library with controls specialized for mobile devices.

Yes Yes Yes sap.m

sap.me

SAPUI5 library with controls specialized for mobile devices (extension).

Yes Yes Yes sap.me

sap.makit

SAPUI5 library contains the makit charts.

Yes Yes -- sap.makit

sap.ui.ux3

SAPUI5 library with controls that implement the SAP User Experience (UX) Guidelines 3.0

-- Yes Yes sap.ui.ux3

sap.viz

SAPUI5 library containing chart controls based on the VIZ charting library

Yes Yes Yes sap.viz

More Information

The Controls section of the SAPUI5 Demo Kit provides detailed information including coding samples and details

on the properties, aggregations and events: SAPUI5 Demo Kit: Controls

The API reference for all libraries can be found here: SAPUI5 Demo Kit: API Reference

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 55

1.1.2.3.1 Artifacts

The table gives an overview of the artifacts used in UI development toolkit for HTML5 (SAPUI5).

Artifact Description

Library Top-level structural unit in SAPUI5

Libraries are the master artifacts in the SAPUI5 extensibility concept. They bundle a set of controls and related types and make them consumable by Web applications. There are predefined and standard libraries, such as sap.ui.commons with many commonly used controls. At the same time, it treats custom UI librares as first-class citizens, making it easy for you to write and use your own controls alongside the predefined controls.

Element Basic building block for SAPUI5 interfaces

Elements are reusable entities with properties, events, methods, and relations. The most important relations are aggregations to other UI elements, and in this way a tree structure of elements can be created.

control Subclass of an element, which can be used as root of a tree structure

Controls serve as an entry point, especially for rendering purposes. They are responsible for appearance and user interaction of a rectangular screen area. Examples for controls are Button, Label, TextField, or Table.

In addition to controls, the platform also provides elements that are not controls and are not used as root of the tree structure, but as dependent parts within it, for example TableRow and TableCell.

property Properties have a name and an associated data type and a well-defined default value expressed as a literal of the respective data type. Properties can be accessed from the application code by means of the element's API as getters and setters, but are also used read-only by a control renderer.

data type First class entities in the meta model; allow reuse of types across libraries and the extensibility of the type system

The SAPUI5 core library (sap.ui.core) provides a predefined set of types that can be used in other libraries.

aggregation Type of relation between UI elements defining aparent-child relation within the tree structures

56 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Artifact Description

Aggregations are relation types where the related entities are UI element types. The parent end of an aggregation has cardinality 0..1 and the child end can either have cardinality 0..1 or 0..*. The element's API as generated by SAPUI5 tools offers consistent methods for aggregations, for example, to get, set, or remove target elements.

Examples for aggregations are table rows and table cells or the content of a table cell.

association Type of relation between two UI elements, independent of the parent-child relation within the tree structure

SAPUI5 supports directed outgoing associations to a target of cardinality 0..1. Associations represent a loose coupling and are, thus, implemented by storing the ID of the target element instance. A typical example is the association between a label and its field.

event Events have a name and any number of parameters. The element's API offers support to manage event subscriptions.

1.1.2.4 SAPUI5 Components

Components are independent and resuable parts used in SAPUI5 applications. An application can use components from different locations from where the application is running. Thus, components can be developed by different development teams and be used in different projects.

NoteConstraints due to cross-origin issues also apply to components.

Components also support the encapsulation of closely related parts of an application into a particular component. This makes the structure of an application and its code easier to understand and to maintain.

SAPUI5 provides the following two types of components:

● UI components (class: sap.ui.core.UIComponent)UI components represent a screen area or element on the user interface, for example, a button or a shell, along with the respective settings and metadata.

● Faceless components (class: sap.ui.core.Component)Faceless components do not have a user interface and are used, for example, for a service that delivers data from a back end system.

The sap.ui.core.Component class is the base class for UI and faceless components. To extend the functionality, components can inherit from their base class or from another component.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 57

Structure of a Component

A component is a folder. The folder name defines the component name and contains all optional and required resources that are used in the component except for the required SAPUI5 libraries and child components. Optional resources are, for example, the CSS and internationalization files, views, and images. The following files are mandatory for components:

● component.jsThis is the component controller and provides the runtime metadata (properties, aggregation, events) and the component methods. The name parameter that is passed to the component constructor represents the package name under which you can find the component.

● component.jsonThis is the component descriptor and contains the design-time metadata; you need this file for design-time environments such as the AppDesigner. The file is not loaded during runtime.

NoteAll paths within a component are relative paths to the component.js file and not to the index.html file.

The following figure gives an example of a component folder structure.

The ComponentContainer control wraps a UI component. You use the control in the SAPUI5 control tree in the same way as any other control.

Related Information

Defining a Component for SAPUI5 from Scratch [page 130]Describes how to define a component for SAPUI5 from scratch

58 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.2.5 Extensibility Concept: Adapting SAPUI5 Applications

SAPUI5 supports the adaptation of standard applications to specific requirements. The information about the adapted objects is stored in the component configuration. The standard application itself is not changed. The customized application becomes the start-up project and launches the standard application with the additional customizing configuration.

SAPUI5 supports the following adaptations of the standard::

● View extensions by using extension points to insert custom content (views or fragments)● Replacing standard views with customized views● Modifying views by changing specific properties● Controller extensions by adding code or overriding existing code● Customizing i18N resource texts

1.1.3 Developing User Interfaces with SAPUI5

1.1.3.1 Bootstrapping and Configuration of SAPUI5

This section provides information about bootstrapping and configuration options for SAPUI5.

To use SAPUI5 for your application, you must load and initialize SAPUI5 in your HTML page. You can use the SAPUI5 bootstrap script in your page to initialize SAPUI5 runtime automatically as soon as the script is loaded and executed by the browser. For simple use cases as well as the default SAPUI5 installation, this is sufficient to build and run UIs.

Additionally, you can specify the set of SAPUI5 libraries and the theme used for your application in the configuration settings.

The following code snippet shows a typical bootstrap script tag:

#!text/html <script id="sap-ui-bootstrap" type="text/javascript" src="resources/sap-ui-core.js" data-sap-ui-theme="sap_goldreflection" data-sap-ui-libs="sap.ui.commons" > </script>

The attributes data-sap-ui-theme="sap_goldreflection" and data-sap-ui-libs="sap.ui.commons" already provide examples of how SAPUI5 runtime can be configured to the needs of an application.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 59

Related Information

Bootstrapping: Loading and Initializing SAPUI5 in HTML Pages [page 60]Initialization Process [page 65]Configuration of the SAPUI5 Runtime [page 66]

1.1.3.1.1 Bootstrapping: Loading and Initializing SAPUI5 in HTML Pages

To use SAPUI5 for your application, you must load and initialize SAPUI5 in your HTML pages. For this, SAPUI5 provides several bootstrap files to support different use cases of bootstrapping. All supported use cases have in common that you need to load and execute at least one SAPUI5-specific JavaScript resource.

The following table gives an overview of the most important resources and the respective use cases. The resource names refer to the resources/ folder in the SAPUI5 installation. The actual base URL depends on your platform and administrative setup.

Resource Description

sap-ui-core.js This is the standard bootstrap file. It already contains jQuery, jquery-ui-position and only the minimum required parts of the SAPUI5 core library (sap.ui.core). Required files are loaded dynamically using XMLHttpRequest (XHR).

For more information, see Standard Variant for Bootstrapping.

sap-ui-core-nojQuery.js You use this bootstrap file for applications with their own jQuery version. It also contains the minimum required parts of the SAPUI5 core library, but not jQuery and jquery-ui-position.

For more information, see noJQuery Variant for Bootstrapping.

sap-ui-core-all.js This bootstrap file contains almost all resources of the sap.ui.core library. Only a few duplicates, such as multiple jQuery versions, testing resources, and so on, are omitted. If you use this file for bootstrapping, the *-all.js file is also loaded for all other libraries. This reduces the number of JavaScript requests to the number of libraries (typically 1..4).

NoteTo ensure proper encapsulation, the *-all.js files will be renamed in future versions of SAPUI5. The sap-ui-

60 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Resource Description

core-all.js file remains as is, but for the files for other libraries a name relative to the libary will be used, for example sap/ui/commons/library-all.js. Applications must not address these files directly as SAPUI5 runtime loads them. Only sap-ui-core-all.js can be directly referenced in the bootstrap tag.

For more information, see All-in-one per Library Variant for Bootstrapping.

sap/ui/core/library-preload.js This bootstrap file is similar to the sap-ui-core-all.js file, but the modules are parsed and executed only on demand, and not immmediately.

CautionAn application must not reference this file. If the configuration option is set to preload, SAPUI5 automatically loads the file.

For more information, see Preload Variant for Bootstrapping.

sap-ui-core-lean.js This bootstrap file is similar to the sap-ui-core.js file, but in this use case only the jQuery and one SAPUI5 file are loaded immediately and the other files are loaded dynamically.

NoteThis use case is usually not used and may be removed in future.

sap-ui5.js This bootstrap file contains all JavaScript modules from the sap.ui.core, sap.ui.commons, sap.ui.table and sap.ui.ux3 libraries. If you use this file for bootstrapping, you only need one single request, but the loading time may be longer as the loading time for other use cases. Another drawback of this use case is the fixed set of libraries.

This file is only available on platorms based on the sapui5.war or sapui5-static.zip artifacts. The OSGi/Eclipse versions (com.sap.ui5.core.jar), for example, do not contain this file.

For more information, see sap-ui5 Variant for Bootstrapping.

sap-ui-custom*.js This bootstrap file is reserved for custom merged files created by the application.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 61

Resource Description

NoteThe proposed naming scheme for these files needs to be adapted in future versions for the same encapsulation reasons as mentioned above.

Related Information

Initialization Process [page 65]

Standard Variant for Bootstrapping

The standard variant is the most common use case for bootstrapping. In this variant, you include the sap-ui-core.js file in your HTML page. This variant is self-contained, meaning that it already contains jQuery as well as some jQuery plugins. An applications only specifies the sap-ui-core.js file on its page and SAPUI5 runtime does the rest automatically.

<script id="sap-ui-bootstrap" src="resources/sap-ui-core.js" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection" > </script>

SAPUI5 synchronously loads the libraries specified in the data-sap-ui-libs configuration option. If a libary requires a library that is not specified in the configuration, SAPUI5 loads this library automatically. You use the data-sap-ui-theme configuration option to specifiy the style sheet you want to load for all libraries.

Subsequent to the bootstrap script tag, an application can call most of the SAPUI5 APIs. The application can access the core APIs, or instantiate, configure, and place controls. The document object model (DOM), however, can only be accessed after the controls have been rendered, that is, only after the document is ready. The application can use the attachInitEvent method to be notified about that event.

NoteIn the default configuration, SAPUI5 automatically activates the preload=sync mode when running from optimized sources. For more information, see Preload Variant for Bootstrapping.

Related Information

Configuration of the SAPUI5 Runtime [page 66]

62 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

noJQuery Variant for Bootstrapping

You can use the noJQuery variant for bootstrapping if your application already integrates jQuery and/or if you want to use a jQuery version that is different to the version integrated in SAPUI5. In this variant, you include the resources/sap-ui-core-noJQuery.js file in your HTML page. Make sure that jQuery and jquery-ui-position have been loaded beforehand. See the following code snippet for an example.

<!-- include some jQuery version --> <script src="my-jQuery-min.js" ></script>

<!-- application doesn't have its own jquery-ui-position, so it might use the one from SAPUI5 --> <script src="resources/jquery-ui-position.js" ></script>

<!-- now booting SAPUI5 --> <script id="sap-ui-bootstrap" src="resources/sap-ui-core-nojQuery.js" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection" > </script>

Preload Variant for Bootstrapping

In the preload variant, SAPUI5 loads all JavaScript modules of a library in advance with one single request. The runtime executes the code only if the application requires the module. Thus, the preload variant significantly reduces the number of roundtrips. To activate the preload variant, set the preload configuration parameter with one of the following values:

● syncIf you set the preload configuration parameter to synch, the runtime loads the modules for all declared libraries synchronously. After processing the bootstrap tag, all preload files of all libraries are loaded and the libraries are initialized as usual. The preload=sync mode should be transparent for most applications.

● asyncIf you set the preload configuration option to asynch, the runtime loads the modules for all declared libraries asynchronously. Thus, any code that follows the SAPUI5 bootstrap tag can not be sure that the SAPUI5 classes are available already. Therefore, the application must delay the access to the SAPUI5 APIs by using the Core.attachInitEvent method. SAPUI5 supports the asynch mode only for libraries that are loaded by the SAPUI5 core. Libraries that are loaded dynamically by using the sap.ui.getCore().loadLibrary() API will be preloaded with preload=sync.

● autoThe preload=auto configuration parameter is the default value. This mode checks whether SAPUI5 runtime uses optimized sources. If optimized sources are used, it enables the preload=sync option to further optimize the runtime. For normal or debug sources, the preload is deactivated.

NotePreload sources always have to be optimized. Therefore, using the preload variant with the debug configuration parameter is counterproductive and debug always overrides the preload configuration parameter.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 63

You can easily check the preload variant with an existing application by specifying the sap-ui-preload=/mode/ parameter in the start URL by adding the data-sap-ui-preload attribute to the bootstrap tag:

<script id="sap-ui-bootstrap" src="resources/sap-ui-core.js" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection" data-sap-ui-preload="sync" > </script>

NoteThe preload=async option requires active cooperation of the application. It is therefore not activated automatically, but only by configuration.

NoteYou can combine the preload configuration option with other bootstrap variants such as sap-ui-core-noJQuery.

Related Information

noJQuery Variant for Bootstrapping [page 63]Configuration of the SAPUI5 Runtime [page 66]

All-in-one per Library Variant for Bootstrapping

The request behavior of the all-in-one per library variant is similar to the request behavior of the preload=sync variant, but it immediately executes all code for a library. This variant is a predecessor of the preload variant and should no longer be used.

sap-ui5 Variant for Bootstrapping

The sap-ui5 variant is a predecessor of the preload variant. It loads all classes and controls of the four standard SAPUI5 libraries sap.ui.core, sap.ui.commons, sap.ui.table, sap.ui.ux3 with one single request. The sap-ui5 variant has the following constraints:

● You can not extend the set of libraries. For custom libraries you must use the all-in-one variant instead.● All the contained code is executed. This may increase the initial startup time of the application depending on

the browser, the client computer or device, and so on.● The file size is huge.

We recommend to use the preload variant instead. Keep in mind that the preload variant is used automatically for optimized sources.

64 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.1.2 Initialization Process

During the initialization of SAPUI5 runtime, the following steps are executed:

1. The jQuery plugins, which are mainly located in the jQuery.sap namespace, provide fundamental functionality of SAPUI5, such as the modularization concept, a small logging framework, performance measurement, and so on.

2. If not already available, the global object sap is created.3. The sap.ui.core.Core class is executed with all its dependencies.4. The runtime configuration is determined from different sources.5. All libraries and modules declared in the configuration as well as their dependencies are loaded.6. For each loaded library, the style sheet of the configured theme is added to the page.7. When all libraries are loaded and the document is ready, the initEvent of the core is fired and all registered

handlers are executed.

Loading of Additional Resources During Bootstrap

During bootstrap, SAPUI5 runtime loads and interprets the following additional resources for each control library that is loaded:

1. Library bootstrap file /''context-path''/resources/''library-name''/library.jsA JavaScript file that contains the JavaScript code for all enumeration types provided by the library as well as library-specific initialization code that is independent from the controls in the library. The file calls the sap.ui.getCore().initLibrary method with an object that describes the content of the library (list of contained controls, elements etc.). For libraries that have been developed with SAPUI5 application development tools or the SAPUI5 offline build tools, this file is generated automatically during the build.

2. Library style sheet file /''context-path''/resources/''library-name''/themes/''theme-name''/library.cssA standard CSS file that contains all styles relevant for this library. For libraries that have been developed with the SAPUI5 application development tools, this file is generated automatically during the build.

Dynamic Loading of Libraries

In addition to declaring libraries in the runtime configuration, you can also use sap.ui.getCore().loadLibary() to load an additional library at runtime.

You can use all controls from these libraries after loading. The restriction that document object model (DOM) access is only possible after document.ready and rendering applies for these libraries in the same way as for the declared libaries.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 65

1.1.3.1.3 Configuration of the SAPUI5 Runtime

SAPUI5 provides the following options for providing configuration settings for SAPUI5 runtime:

● Runtime default values● Individual script tag attributes● Single and complex configuration attributes● Global configuration object● URL parameters● Runtime configuration object

The following order of significance applies:

Attributes of the DOM reference override the system defaults. URL parameters override the DOM attributes; empty URL parameters set the parameter back to its system default. If you call setters at runtime, any previous settings calculated during object creation are overwritten.

Configuration Using Runtime Default Values

SAPUI5 runtime provides a default value for each configuration option. For an overview of the default values, see Configuration Options.

Individual Script Tag Attributes

You can specify the configuration settings by means of one or more attribute in the bootstrap script tag. For each configuration option, SAPUI5 accepts an attribute with a corresponding name in the bootstrap script tag with the following information:

● Attribute nameThe attribute name is composed of the configuration option name and the data-sap-ui- prefix. The first part of the prefix (data-) is necessary to comply with the W3C recommendations for custom attributes in HTML. The second part (-sap-ui-) separates SAPUI5 attributes from custom attributes defined by any other framework.Attribute names in HTML are case-insensitive and the same applies to the configuration attribute names. However, SAPUI5 has defined some configuration options names in camel case, for example originInfo. SAPUI5 converts these names automatically to lower case when accessing the configuration.

● ValueElement attributes in HTML have a string value by definition. For configuration options of type string, the attribute value is equivalent to the value of the option.

NoteIf the value contains specific HTML characters, such as '<' or '>', or if the value contains the same quote character that is used to wrap the attribute value, the usual HTML escape mechanisms must be used: Use entities for the specific HTML characters, for example &lt; instead of <, and switch the type of quotes from single to double or vice versa.

66 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

For configuration options that are not of type string, the format of the allowed values has to be defined as follows:

Type Notation/Values

string Just a string, but escaped according to the HTML conventions

boolean 'true' and 'x' are both accepted as true values (case-insensitive), all others are false. We recommend to use 'false' for false values

int Any integer value

string array Comma separated list of values; comma is not supported in the values (no escaping)

map from string to string JavaScript object literal (preferably JSON syntax)

Single and Complex Configuration Attributes

Instead of attaching individual options with individual configuration attributes to the script tag, you can use a single attribute with a more complex structure. The attribute name for the complex configuration is data-sap-ui-config. Its content is similar to the global configuration object, but without the enclosing parenthesis: It is a comma separated list of key/value pairs.

NoteThe usual HTML escape mechanisms must be used if the value contains specific HTML characters (<, >, &) or the quote character that is used to enclose the attribute value.

#!text/html <script id="sap-ui-bootstrap" type="text/javascript" src="resources/sap-ui-core.js" data-sap-ui-config="theme:'sap_platinum',libs:'sap.ui.commons'" > </script>

Global Configuration Object

Another way of specifying the configuration is to create a property in the global window object with property name sap-ui-config. The property must be a simple object, where each property represents the configuration option of the corresponding name.

NoteThe name of the window property intentionally is not a valid JavaScript identifier. This helps to avoid conflicts with typical JavaScript coding and the structured nature of the name is intended to avoid conflicts with SAP objects. To define the object, quotes must be used.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 67

NoteIf a configuration option has a name that is not a valid JavaScript identifier or that is a reserved token in JavaScript, the property name in the configuration object must be quoted. Currently, such a configuration option does not exist.

NoteAs the configuration is evaluated during bootstrap, the configuration object must be created before SAPUI5 is booted. Otherwise, the contained configuration cannot be evaluated. As a consequenece, using the global configuration object requires another script tag in front of the bootstrap script tag. It is up to the application whether it uses an inline script tag or a separate JavaScript file, which is loaded via a script tag, for this purpose. If you use a dedicated file, it may require more work initially, but offers the following advantages:

● Several pages can share the file and, thus, use the same configuration.● The Content Security Policy (CSP) mechanism as introduced, for example, by FireFox 4.0 and others

requires the use of a file.

The following code snippet shows an example for an inline script tag:

#!text/html <script type="text/javascript"> window["sap-ui-config"] = { theme : "sap_platinum", libs : "sap.ui.commons", }; </script> <script id="sap-ui-bootstrap" type="text/javascript" src="resources/sap-ui-core.js" > </script>

Although this option requires an additional script/script tag, it offers the possibility to share configuration between pages, it can be used in environments where the scrip tag cannot be influenced (for example, because it is created out of some configuration, like in some mashup frameworks), and it allows to provide configuration before the core boots.

URL Parameters

You can specify confiuration parameters by adding them as parameters to the start URL of an application. The name of the URL parameters is composed of the name of the configuration option and the sap-ui- prefix.

NoteThe W3C proposed data- prefix is not needed and even not allowed here as all URL parameters are kind of custom parameters.

The value of a URL parameter is of type string and the same type mapping as for HTML attributes applies. However, URLs require a different encoding than HTML; they use, for example % encoding instead of entity encoding.

68 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

For security reasons, only some configuration options can be set via URL parameters. An application can set the ignoreUrlParameters option to true to disable URL configuration parameters completely.

Runtime Configuration Object

The above described options for configuration are all evaluated during SAPUI5 runtime boots. After that, all changes to these parameters are ignored. The final configuration result can be read by means of the sap.ui.getCore().getConfiguration() method.

The same object also provides set methods for a very limited set of configuration options. Such options can be modified at runtime and the runtime and/or the controls can react on the configuration changes. The most prominent (and so far only) example for such a configuration option is the theme.

Related Information

Configuration Options [page 69]

Configuration Options

The following list is an abstract of the available configuration options. For a complete list of all current configuration options, see the documentation of sap.ui.core.Configuration in the API reference at

sap.ui.core.Configuration .

Option Type Default Value URL Modifiable at Runtime

Description

theme string base x x This configuration parameter defines the theme that shall be used for the current page; you can change the theme at runtime by calling sap.ui.getCore().applyTheme().

language string user language x This configuration parameter defines the language that shall be used for

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 69

Option Type Default Value URL Modifiable at Runtime

Description

localized texts, formattings, and so on.

The default value is not static, but determined from the browser or user language in the following order:

1. navigator.language

2. navigator.browserLanguage

3. navigator.userLanguage

formatLocale string undefined x This configuration parameter defines the locale used for formatting purposes; the default values for the locale are derived from the language.

accessibility boolean true x If set to true, the SAPUI5 controls are rendered for or running in accessibility mode.

animation boolean true x If set to true, animations are generally allowed in SAPUI5 controls.

rtl boolean false x If set to true, all controls are rendered in right-to-left (RTL) mode; not yet determined automatically.

70 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Option Type Default Value URL Modifiable at Runtime

Description

debug boolean false x If set to true, the debug sources are loaded; if the bootstrap code is loaded from an optimized source, the bootstrap will be aborted and start anew from a debug source.

inspect boolean false x If set to true, the sap-ui-debug.js module is included and provides some supportability features

originInfo boolean false x If set to true, additional information for text resources is provided that allows to determine the origin of a translated text on the UI

noConflict boolean false ! If set to true, SAPUI5 forces jQuery into noConflict mode.

noDuplicateIds

boolean true x If set to true, this configuration parameter enforces that the same IDs are not used for multiple controls; we highly recommend this check as duplicate

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 71

Option Type Default Value URL Modifiable at Runtime

Description

IDs may cause unforseeable issues and side effects.

trace boolean false ! If set to true, this configuration parameter activates an overlay div that contains a trace.

logLevel 0|1|2|3|4|5|6|NONE|FATAL|ERROR|WARNING|INFO|DEBUG|ALL

ERROR x x This configuration parameter sets the log level to the given value; for minified (productive) sources, the default level is ERROR, for debug sources it is DEBUG. At runtime, you can modify the log level by using the jQuery.sap.log.setLevel method.

modules string[] [ ] ! This configuration parameter defines a list of JavaScript modules that shall be loaded after the code has been initialized.

areas string[] null ! x This configuration parameter defines UI areas that shall be created in advance; use sap.ui.getCore().createUIArea to create new UI areas and sap.ui.getCore().getUIArea(id).destroy() to delete existing UI areas at runtime.

72 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Option Type Default Value URL Modifiable at Runtime

Description

libs string[] [ ] ! x This configuration parameter defines a list of libraries that shall be loaded initially; use the loadLibrary() method to load further libraries.

themeRoots object undefined X sap.ui.getCore().setThemeRoot()

This configuration parameter defines the location of themes.

onInit code undefined ! This configuration setting defines if code has to be executed after the initialization

uidPrefix string '--' ! Prefix to be used for automatically generated control IDs; must be choosen carefully to avoid conflicts with IDs defined by the application or DOM IDs.

ignoreUrlParams

boolean false ! Security-relevant parameter that allows applications to disable configuration modifications via URL parameters.

weinreServer string URL to a WEINRE server to be used for debugging purposes; if set, SAPUI5 automatically includes the WEINRE target modules.

weinreId string x

xx-loadAllMode

boolean false !Note

This is an experimental

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 73

Option Type Default Value URL Modifiable at Runtime

Description

feature and may be modified or removed in future versions.

This configuration parameter is used internally by SAPUI5 runtime. To activate it, load sap-ui-core-all.js instead of sap.ui.core.js.

preload not specified, auto, sync, or asynch

auto ! Between loading SAPUI5 core runtime and further libraries, the so-called preload files are loaded. They contain all modules of a library. The modules are only loaded, but not executed, thus reducing initialization time.

The values are used as follows:

● When set to auto, SAPUI5 runtime automatically uses sync when running from optimized sources.

● When set to sync, the preload files for the

74 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Option Type Default Value URL Modifiable at Runtime

Description

declared libraries are loaded synchronously.

● When set to async, the preload files are loaded asynchronously.

● For any other value (for example blank), the preload feature is deactivated and modules are loaded on demand.

xx-test-mobile

boolean false xNote

This is an experimental feature, and may be modified or removed in future versions.

This configuration parameter activates support for mobile device-specific events, such as touch events. This enables you to test standard SAPUI5 controls on mobile devices.

xx-fakeOS string undefined xNote

This is an experimental feature and may be

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 75

Option Type Default Value URL Modifiable at Runtime

Description

modified or removed in future versions.

You use this configuration parameter to simulate iOS, Android and BlackBerry on desktop PCs for easier development of mobile apps and controls. The following values are supported:

● ios● android● blackberry

The parameter modifies the user-agent and runtime and theming act as the selected mobile platform. This includes Browser detection mechanisms such as jQuery.browser.

NoteThis configuration parameter only works on desktop WebKit browsers, such as Chrome and Safari. On other browsers and on mobile devices the configuration

76 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Option Type Default Value URL Modifiable at Runtime

Description

parameter has no effect.

1.1.3.2 UI Control Constructors

The constructor is a special type of subroutine called to create an object. The constructor uses values to set control properties, thus preparing the new object for use. The following paragraphs explain the use of UI control constructors in SAPUI5.

In SAPUI5, control constructors accept the following arguments in the specified order:

1. An optional unique identifier of type string which must either be the first argument, or omitted altogether. If you omit the ID, the SAPUI5 framework automatically computes an ID. Specifying your own identifier allows your application to easily find the control and, for example, retrieve the current user input from it. Alternatively, you can keep a reference to the control in a variable.

2. One JSON-like object (object literal) as mSettings parameter that defines values for any property, aggregation, association, or event. If a specific name for a control is ambiguous, meaning that a property has the same name as an event, the framework assumes in the following order: Property, aggregation, association. To resolve ambiguities, add the respective prefix to the key in the JSON object: "aggregation:", "association:", or "event:".

The following code snippet shows an example of a constructor that is called to create a new text field "Hello World" with the specified tooltip and width:

var oTextField = new sap.ui.commons.TextField("testTextField", {value : "Hello SAPUI5", tooltip: "This is an example tooltip", width: "100px"});

The above example is an abbreviated version of the following code snippet with a detailed list of statements, which is alternatively supported:

var oTextField = new sap.ui.commons.TextField("testTextField"); oTextField.setValue("Hello SAPUI5"); oTextField.setTooltip("This is an example tooltip"); oTextField.setWidth("100px");

The supported parameters are documented in the JsDoc of the respective control.

1.1.3.3 UI Control API: Event Handling

You can register JS event handlers for any controls that raise events. The control API provides attach<EventName> methods as shown in the following example:

#!js

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 77

var oButton = new sap.ui.commons.Button("b1", {text:"Go", width:"80px"}); oButton.attachPress( function (oControlEvent) { alert("You clicked on Button " + oControlEvent.getSource().getId()); });

NoteYou can register the event handler for button control also directly via the button constructor.

#!js

function buttonPressed(oControlEvent) { alert("You clicked on Button " + oControlEvent.getSource().getId());};var oButton = new sap.ui.commons.Button("b1", {text:"Go", width:"80px", press:buttonPressed});

For more information on control constructors, see UI Control API: Using JSON Data in UI Control Constructors.

SAPUI5 describes events such as "press button" as "semantic events". Semantic events do not exist as native HTML browser events. The UI control implementation is responsible for mapping native browser events to semantic events. For button control, for example, the button implementation must define a mapping of the "onclick" event to the "press" event. This can be done in the button behavior file as follows:

#!js

/** * Function is called when button is clicked. */sap.ui.commons.Button.prototype.onclick = function(oBrowserEvent) { if (this.getEnabled()) { this.firePress({id:this.getId()}); }};

1.1.3.4 Models and Data Binding

Data binding is used to bind two data or information sources together to keep them in sync. If data binding is implemented and defined properly, all changes in one data source are automatically reflected in the other data source. Usually, the UI uses data binding to bind UI controls to a data source that holds the application data, so that the controls are updated automatically whenever application data is changed.

To achieve this, there is a model and a data binding. The model instance holds the data and provides methods to set the data or to retrieve data from a server. It also provides a method for creating bindings to the data. When this method is called, a data binding instance is created, which contains the binding information and provides an event, which is fired whenever the bound data is changed. An element can listen to this event and update its visualization according to the new data.

The term data binding is also used when changes in the control cause updates in the underlying application data, such as data being entered by a user. This is called bi-directional binding or two-way binding.

A Web application should support several data sources, such as JSON, XML, Atom, or OData. However, the way in which data binding is defined and implemented within the UI controls should be independent of the respective

78 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

data source. It should also be possible to create a custom model implementation for data sources that are not yet covered by the framework or are domain-specific.

Related Information

Data Binding: Getting Started [page 79]Models and Data Binding in Applications [page 83]This page describes how data binding can be used in SAPUI5 applications. It describes how to create a model instance, how to assign it to the UI, and how the controls on the UI can be bound to the model.

Binding Types [page 98]

1.1.3.4.1 Data Binding: Getting Started

This chapter gives an overview of how to use data binding in conjunction with SAPUI5 controls in a simple application. It provides information about binding data to a property of a control (property binding) as well as binding a collection of values (aggregation/list binding).

The following steps show how you use data binding in your application:

1. Decide on the model you want to use. Depending on the service or backend type, you can choose a different model that supports your backend. Currently, model implementations for JSON, XML format, and OData services are available. If no suitable model for your backend is available, you can use your own implementation.

2. Create a model instance.3. Create a control instance.4. Bind properties or lists of the control to your model.5. Unbind properties if you wish.

The following example uses the JSON model. This model is not specific to a particular backend type or implementation. The only requirement is that the data for the model is provided in JSON format.

The JSON model supports two-way/bidirectional data binding by default, which means that the model will automatically reflect changes to the view and vice versa.

Defining the Data

To define the data, proceed as follows:

1. Create a simple HTML page and load the SAPUI5 runtime.2. Create the data that you want to bind to a control property. As we are using the JSON model, you need to

provide this data in JSON format.3. Place the code into your sample page:

// JSON sample datavar data = {

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 79

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

Creating a Data Binding Model Instance

Now you create a new JSON data model and add the data you have created to the model, so that the data is stored there and can be used for binding. Finally, you attach the model to the SAPUI5 core so that it can be used by various controls. It is also possible to attach the model to a specific control by calling oElement.setModel(oModel).

// create JSON model instancevar oModel = new sap.ui.model.json.JSONModel();// set the data for the modeloModel.setData(data);// set the model to the coresap.ui.getCore().setModel(oModel);

Creating Controls and Property Binding

Now you can create the SAPUI5 controls and define the binding to the properties. In the sample, you first define a TextView control and a TextField control. Both controls should display the firstName property of the model. The corresponding control properties have to be bound to the model property. You do this directly in the control constructor by using {} braces and specifying the path to the property in the model. You do this for both controls.

// create your controls var oTextView = new sap.ui.commons.TextView("textView", { // bind text property of textview to firstName property in the model text: "{/firstName}", tooltip: "First Name"});var oTxt = new sap.ui.commons.TextField("txtField", { // bind text property of textfield to firstName property in the model value: "{/firstName}"});

Next you create a CheckBox control and bind its checked property to the enabled property in the model. You also do this for the previously created TextField by using an alternative binding notation:

// create your controlsvar oChkBx = new sap.ui.commons.CheckBox("box", { // bind checked property against enabled property in the model checked: "{/enabled}", change: handleCheckBoxChange});// generic bind method bindProperty(control property, model property)oTxt.bindProperty("enabled", "/enabled");

function handleCheckBoxChange(oEvent){ var bEnabled = oEvent.getParameter("checked"); // modify the enabled property value in the model to reflect changes

80 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

oModel.setData({enabled: bEnabled}, true); // true means merge the data instead of replacing};

The handleCheckBoxChange method sets the enabled property in the model, depending on the current checked state of the CheckBox.

In a last step, you create a button and define the update method for updating the firstName value in the model with the value of the TextField when the button is clicked.

// create your controlsvar oBtn = new sap.ui.commons.Button({ id: "btn", text: "Trigger Change", press: update});

function update(){ // modify the firstName property value in the model to reflect changes oModel.setData({firstName: sap.ui.getCore().byId("txtField").getValue()}, true);};

When you now open the sample application in the Web browser, you can see that the value of the firstName property is already displayed in the TextView and TextField. When you select the CheckBox, the enabled value is modified in the model (by the handleCheckBoxChange method), and the changes are immediately reflected in all control properties that are bound to this property. In this case, the TextField is enabled or disabled.

As described above, clicking the button modifies the firstName value in the model with the value of the TextView. When this happens, all control properties bound to this model field are updated immediately to reflect the changes (direction Model → View).

Additionally, since the JSON model supports two-way binding, entering a text value into the TextField will also update the corresponding value in the model, and the TextView will display the changes because it is bound to the same property (direction Model ← View).

The page then looks as shown in the following figure.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 81

Aggregation Data Binding in a Simple Application

The above sample covers the binding of single properties to a control property. Now we want to focus on binding a collection of values, for example, binding multiple rows into a table, the values for a ListBox, or the items in a ComboBox.

In this example we use the RowRepeater control and bind it to a collection of data. Again, you start with the definition of data and set it to the model and the model to the core.

//create test datavar dataObject = { data : [{index:0, level: "Warning", description: "HAL: I'm sorry, Dave. I'm afraid I can't do that."}, {index:1, level: "Warning", description: "Windows Boot Manager has encountered a problem."}, {index:2, level: "Error", description: "Failwhale: Twitter is over capacity"}, {index:3, level: "Success", description: "Jun 25 12:20:47 pc1h kernel: lp0 on fire"}, {index:4, level: "Error", description: "Software failure. Press left mouse button to continue. Guru Meditation #00000004,#0000AACB."}, {index:5, level: "Error", description: "[root@localhost root]# Kernel Panic"}, {index:6, level: "Error", description: "That does not compute."}, {index:7, level: "Warning", description: "404 File not found. Stop messing with the URL."}, {index:8, level: "Success", description: "Blue Screen of Death."},};

//create JSON modelvar oModel = new sap.ui.model.json.JSONModel();oModel.setData(dataObject);sap.ui.getCore().setModel(oModel);

The next step covers the creation of the controls and the definition of a single Message control, which will be used as a template for all items in the RowRepeater. The Message control will hold the corresponding level and description values from the model so that these properties are bound to the model:

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

Once the template is defined, you create the RowRepeater control. The RowRepeater has an aggregation rows, which can be any SAPUI5 control. In our case, this is the above mentioned Message control. You create an aggregation or list binding for this rows property. To do this, you specify the name of the array in the JSON model that contains the actual data (path) and also specify the Message row template:

//create the RowRepeater controlvar oRowRepeater = new sap.ui.commons.RowRepeater("rowRepeater", { design : "Standard", numberOfRows : 5, currentPage : 1, title : oTitle, // bind row aggregation rows : {path : "/data", template : oRowTemplate}});

The SAPUI5 runtime clones the row template for each entry in the JSON array for the data property and also binds the description and level properties for each message item.

82 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The following figure shows a sample page.

1.1.3.4.2 Models and Data Binding in Applications

This page describes how data binding can be used in SAPUI5 applications. It describes how to create a model instance, how to assign it to the UI, and how the controls on the UI can be bound to the model.

SAPUI5 provides several binding modes and provides multimodel support.

Related Information

Creating a Model Instance [page 83]The first step when using data binding is to create a model instance and to provide the data for that model. This is different for each model.

Assigning the Model to the UI [page 95]Defining a Binding Path [page 96]Binding Controls to the Model [page 96]Multimodel Support [page 97]Setting the Default Binding Mode [page 97]When a model instance is created, the instance has a default binding mode. You can overwrite this default setting.

Creating a Model Instance

The first step when using data binding is to create a model instance and to provide the data for that model. This is different for each model.

You choose the model depending on the requirements and the availability of data formats on the server side. To help you to decide which model to choose, see: Models [page 46].

To create a model instance for the respective model, choose one the following procedures:

○ Creating a Resource Model Instance [page 84]○ Implementing a JSON Model [page 85]○ Implementing an OData Model [page 87]○ Implementing an XML Model [page 93]

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 83

○ If none of the predefined model meets your needs, create a custom model implementation, see Implementing a Custom Model.

Creating a Resource Model InstanceThe resource model is used as a wrapper for resource bundles. You can, for example, bind texts of a control to language-dependent resource bundle properties.

1. With a bundleName, that is, the name of a resource bundle and equals a SAPUI5 module name within the require/declare concept

2. With a bundleUrl that points to the resource bundle

If you use the bundle name, the file must have the .properties suffix. If you do not specify a locale, the system uses the login language

var oModel = new sap.ui.model.resource.ResourceModel({bundleName:"myBundle",locale:"en"});

NoteIn this ResourceModel implementation you cannot pass parameters to your texts within the resource bundle. If you have to pass parameters, you must do this on your own. Therefore, you can load the bundle yourself or retrieve it from the model.

var myBundle = oModel.getResourceBundle();

After the instance has been created, you have a model containing the resource bundle texts as data.

Related Information

Modularization and Dependency Management [page 152]Localized Texts [page 284]

Binding Path Syntax for Resource ModelsThe ResourceModel has a simple binding path syntax, as it contains only a flat list of properties.

The following example shows a simple resource model that illustrates the possible binding paths: Resource bundle content:

CLOSE_BUTTON_TEXT=CloseOPEN_BUTTON_TEXT=OpenCANCEL_BUTTON_TEXT=Cancel

...Binding paths within the model:

CLOSE_BUTTON_TEXTOPEN_BUTTON_TEXTCANCEL_BUTTON_TEXT

Binding Texts to a Resource BundleTo bind texts of a control in JSON views to a language-dependent resource bundle, define the resource bundle by a name (resourceBundleName property) or a URL (resourceBundleUrl property) and assign an alias (resourceBundleAlias property) for the bundle in the view definition.

84 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The ResourceModel required for binding these texts is created during view instantiation. The model is set as secondary model with the given alias to the view instance. If you want to bind other properties to another model, you have to create the model on your own in the corresponding controller or HTML page and attach it to the view with another alias. The binding itself behaves in the same way as every SAPUI5 data binding and as described above.

1. Deifne the following resource bundle content: MY_TEXT=Hello World2. To bind this resource bundle contetn, insert the following code depending on the view type:

○ For a JSON view, insert the following code:

{ "Type": "sap.ui.core.JSONView", "controllerName":"my.own.views.test", "resourceBundleName":"myBundle", "resourceBundleAlias":"i18n", "content": [{ "Type":"sap.ui.commons.Panel", "id":"myPanel", "content":[{ "Type":"sap.ui.commons.Button", "id":"Button1", "text":"{i18n>MY_TEXT}", "press": "doIt" }] }]}

○ For a XML view, insert the following code:

<core:View resourceBundleName="myBundle" resourceBundleAlias="i18n" controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml"> <Panel> <Button text="{i18n>MY_TEXT}"/> </Panel><core:View>

Related Information

Models and Data Binding [page 78]

Implementing a JSON ModelThe JSON model can be used to bind controls to JavaScript object data, which is usually serialized in the JSON format. The JSON model is a client-side model and, therefore, intended for small datasets, which are completely available on the client. The JSON model does not support mechanisms for server-based paging or loading of deltas. It supports, however, two-way binding.

1. To create a JSON model instance, insert the following code:

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

2. After the instance has been created, there are different options to get the data into the model.

○ The easiest option is to set data by using the setData method:

oModel.setData({ firstName: "Peter",

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 85

lastName: "Pan"});

NoteThe correct JSON notation uses double quotes for the keys and string values.

○ Usually, you do not define your data inline in the application but load it from a server-side service using an XHR request. The JSON model, however, also has a loadData method, which loads the JSON data from the specified URL asynchronously and applies it to the model:

oModel.loadData("data.json");

API Reference: sap.ui.model.json.JSONModel

Sorting and Filtering in JSON ModelsUsing a JSON model, all data is available on the client. Sorting and filtering are also implemented in JavaScript.

This allows the usage of custom sorting and filtering methods in the JSONModel. To define custom methods, set the fnCompare method on the Sorter object or the fnFilter method on the Filter object after creating it.

1. The fnFilter method of the Filter gets the value to test as the only parameter and returns, whether the row with the given value should be filtered or not.

var oFilter = new sap.ui.model.Filter("property");oFilter.fnFilter = function(value) { return (value > 100); };

2. The fnCompare method of the Sorter gets the two values to compare as parameters and returns -1, 0 or 1, dependent which of the two values should be ordered before the other:

var oSorter = new sap.ui.model.Sorter("property");oSorter.fnCompare = function(value1, value2) { if (value1 < value2) return -1; if (value1 == value2) return 0; if (value1 > value2) return 1;};

Binding Path Syntax for JSON ModelsAs the JSONModel only consists of named objects (properties, arrays, or nested objects), it has a simple binding path syntax.

The following example shows a simple JSONModel with the different binding paths:

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

86 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

name: "Susan", phone: "275" } ] }}

Absolute binding paths within this model:

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

Relative binding paths within the "/company" context:

nameinfo/employeescontacts

Relative binding paths within an aggregation binding of "/company/contacts":

namephone

Implementing an OData Model

The OData model enables binding of controls to data from OData services. The OData model is a server-side model: the dataset is only available on the server and the client only knows the currently visible rows and fields. Sorting and filtering is done on the server. The client has to send a request to the server to accomplish these tasks.

NoteBe aware of the Same-Origin-Policy security concept which prevents access to backends on different domains or sites.

1. To create an OData model instance:

var oModel = new sap.ui.model.odata.ODataModel("http://services.odata.org/Northwind/Northwind.svc/");

Requests to the service to fetch data are made automatically according to the data bindings defined in the controls.

The service URL is the first parameter of the constructor. One OData model instance can only cover one OData service. If you need access to multiple services, you have to create multiple instances of the OData model.

2. To add additional parameters:

When using OData services, you can use URL parameters for configuration. SAPUI5 sets most of the required URL parameters automatically according to the data binding. Two options for adding custom parameters to the request exist: URL parameters can be appended to the service URL and a map of parameters can be passed when using bindElement or bindAggregation.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 87

Additional parameters, which are added to the OData service URL, are included in every request sent to the OData server. This is useful for authentication tokens or general configuration options.

var oModel = new sap.ui.model.odata.ODataModel("http://myserver/MyService.svc/?custom1=value1&custom2=value2");

3. For other parameters it makes no sense to include them in every request. These parameters should only be added to specific aggregation or element bindings, for example, $expand or $select. For this, the binding methods can pass a map of parameters, which is then included in all requests for this specific binding. Currently, the ODataModel only supports $expand and $select.

○ To use the $expand parameter see the following snippet below:

oControl.bindElement("/Category(1)", {expand: "Products"});

oTable.bindRows({ path: "/Products", parameters: {expand: "Category"}});

In the first example all products of Category(1) are embedded inline in the server response and loaded in one request. In the second example the Category for all Products is embedded inline the response for each product.

○ The $select parameter returns only the specified properties of requested entries.

oControl.bindElement("/Category(1)", {expand: "Products", select: "Name,ID,Products"});

oTable.bindRows({ path: "/Products", parameters: {select: "Name,Category"}});

In the first example the properties Name and ID ofCategory(1) and all properties of the embedded products are returned. In the second example the properties Name and Category are included for each product. The Category property will contain a link to the related Category entry.

4. To add custom query options:

You can add custom query options by placing them as a query string in the URL. The name of a query string does not begin with a $ character:

http://services.odata.org/OData/OData.svc/Products?x=y

You can also use custom query options as input parameters for service operations. You can specify the custom parameters during aggregation binding as follows:

oTable.bindRows({path: "/Products", parameters: { custom: { param1: "value1", param2: "value2" } }, template: rowTemplate });

For bindElement, you can specify custom parameters as follows:

oTextField.bindElement("/GetProducts", { custom: { "price" : "500" } });

5. To create virtual entries:

You can create empty objects for a specified collection name. The application can bind against these objects. By calling the submitChanges function, you can determine the point in time when these objects are persisted in the backend. The application has to trigger this explicitly. Before the objects are persisted in the backend,

88 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

all created virtual entries are stored in a request queue and can still be removed. The application can choose which properties are included in the created object and may pass own default values for these properties. Otherwise, the property values remain empty.

Make sure that the collection and properties exist on the OData service and are defined in the metadata document as well. Here is an example:

// create an entry of the Products collection with the specified properties and values var oContext = oModel.createEntry("Products",{ID:99,Name:"Product",Description:"new Product",ReleaseDate:new Date(),Price:"10.1",Rating:1}); // use the returned context for binding against this entry oLayout.setBindingContext(oContext); oSimpleListBox.addItem(new sap.ui.core.ListItem({text: "Added entry: " + oContext.getPath()})); // to delete a created entry from the request queue without persisting it provide the created context to the deleteCreatedEntry function oModel.deleteCreatedEntry(oContext);

The createEntry function returns a context object which can be used to bind against the newly created entry. See the following example for how to write the entries in the request queue to the backend:

// provide optional success and error functions which are called for each request in the queue oModel.submitChanges(fnSuccess, fnError);

The default binding mode of the OData model is one-way, but as experimental write support is implemented, two-way binding can be enabled. For more information, see OData Write Suport.

API Reference: sap.ui.model.odata.ODataModel

Binding Path Syntax for OData Models

You access the data provided by the ODataModel according to the structure of the OData service as defined in the metadata of a service. The syntax of the binding path matches the URL path relative to the service URL used in OData to access specific entries or collections. URL parameters such as filters cannot be added to a binding path. The following samples of bindings within the ODataModel are taken from the well-known Northwind demo service.

Absolute binding paths:

/Customers/Customers('ALFKI')/Orders

Relative binding paths within a Customer context:

CompanyNameAddressOrders

Relative binding paths within an aggregation binding of "/Customer('ALFKI')/Orders:

OrderIDShipNameShipAdressEmployee/LastNameOrder_Details/Discount

OData Write Support

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 89

NoteAs these features are experimental, changes in future versions of SAPUI5 may occur. Currently, all write operations have to be performed by the application and are triggered synchronously.

SAPUI5 supports the following operations and features for the OData model:

● write● create● remove● update● read● get metadata service document● Cross-site request forgery (XSRF) token support for the REST library● refresh

The default binding mode is sap.ui.model.BindingMode.OneWay. You can also set the binding mode to sap.ui.model.BindingMode.TwoWay.

Create Request

The create function triggers a POST request to an OData service which was specified during creation of the OData model.

The application has to specify the collection where to create the entry and the entry data payload.

To get the result of the request, the application can hand over callback handler functions. To recreate and update the bindings, a refresh is triggered automatically after the successful creation.

The following code triggers a new entry in the Products collection:

var oEntry = {};oEntry.Name = "IPad";oEntry.Price = "499$";oModel.create('/Products', oEntry, null, function(){ alert("Create successful"); },function(){ alert("Create failed");});

Delete Request

The remove function triggers a DELETE request to an OData service which was specified during creation of the OData model. The application has to specify the path to the entry which should be deleted. To update the bindings in the model, a refresh is triggered automatically after successful deletion.

A single parameter oParameters can be passed into the function and can carry all optional attributes, such as attributes for success and error handling functions as well as ETag attributes. ETags can be used for concurrency control if the OData service is configured to provide them. For more information, see the section about concurrency control and ETags in the OData documentation.

90 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

If an ETag is specified in oParameters, it will be used inthe If-Match-Header nstead of any ETag found in the metadata of an entry. If not, the ETag is retrieved from the entry's metadata. In fo ETag is found, no If-Match-Header will be used.

The following code delets the product entry with ID=1 from the Products collection of the data service:

oModel.remove('/Products(1)', null, function(){ alert("Delete successful"); },function(){ alert("Delete failed");});

Update Request

The update function triggers a PUT request to an OData service which was specified during creation of the OData model. See the ODataModel API for information about attribute use.

The application has to specify the path to the entry which should be updated with the specified updated entry.

After a successful request to update the bindings in the model, a refresh is triggered automatically.

The following code updates the price:

var oEntry = {};oEntry.Price = "599$";oModel.update('/Products(1)', oEntry, null, function(){ alert("Update successful"); },function(){ alert("Update failed");});

The flag bMerge has been introduced to also allow a MERGE request to perform a differential update.

Read Request

The read function triggers a GET request to a specified path which should be retrieved from the OData service which was specified during creation of the OData model.

The retrieved data is returned in the success callback handler function.

oModel.read('/Products(1)', null, null, true, function(oData, oResponse){ alert("Read successful: " + JSON.stringify(oData)); },function(){ alert("Read failed");});

Refresh

The Refresh function triggers a refresh for each binding to check if a value has been updated, or not. For a list binding a new request is triggered to reload the data from the server.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 91

Additionally, if the XSRF token is not valid any more, a read request is triggered to fetch a new XSRF token from the server.

XSRF Token

To address the challenge of Cross Site Request Forgery an OData service might require XSRF tokens for change requests by the client application for security reasons. In this case the client has to fetch a token from the server and send it with each change request to the server.

The OData model fetches the XSRF token when reading the metadata and then automatically sends it in each write request header. If the token is not valid any more a new token can be fetched by calling the refresh function on the OData model.

Metadata

The getServiceMetadata function returns the parsed metadata document as a JavaScript object.

Experimental Two-Way Binding

NoteThis feature is experimental and may change in future versions of SAPUI5.

The two-way binding mode enables the application to update values of a single collection entry without triggering an immediate change request. create and delete operations are not collected and can be called by the application as described above.

If the two-way binding mode is enabled, the setProperty function of the OData model is called automatically to update the value in the specified entry upon user input. If an update to a property of another entry is performed and there is already an update to an existing entry pending, a rejectChange event is fired and no change to the property value is stored in the model. The application can register to this event. Thus, before updating a different entry, the application has to submit or reset existing changes of the current entry:

● To reset the current changes the application can call the resetChanges function.● To trigger the final update request for the modified entry the application should call the submitChanges

function.

Callback handlers for these functions can be handed over as parameters.

To enable the two-way binding for the OData model the default binding mode has to be changed as follows:

oModel.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay);

After the binding is done, the application should attach to the rejectChange event to handle the user modifications to different entries accordingly and, for example, allow or reject user input for a specific entry.

oModel.attachRejectChange(this,function(oEvent){ alert("You are already editing another Entry! Please submit or reject your pending changes!");});

92 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The application can use the hasPendingChanges function to determine if there is a pending change.

The application can then decide (or let the user decide) when to submit or reject the changes:

var oUpdateBtn = new sap.ui.commons.Button({ text : "Update", style : sap.ui.commons.ButtonStyle.Emph, press : function(){ oModel.submitChanges(function(){ alert("Update successful");); },function(){ alert("Update failed");}); }});

var oCancelBtn = new sap.ui.commons.Button({ text : "Cancel", style : sap.ui.commons.ButtonStyle.Reject, press : function(){ oModel.resetChanges(); }});

The submitChanges function also has an optional parameter oParameters which currently can have an attribute for an ETag.

Implementing an XML ModelThe XML model allows to bind controls to XML data. It is a client-side model intended for small datasets, which are completely available on the client. The XML model does not contain mechanims for server-based paging or loading of deltas. It supports two-way binding.

1. To instantiate the model:

var oModel = new sap.ui.model.xml.XMLModel();

2. The XML model also has a setData method. As XML documents cannot be embedded inline in JavaScript, the XMLModel uses an XML document reference as a parameter.

oModel.setData(oXMLDocument);

3. To create inline XML data or to get XML data as a string, the XML model provides a setXML method. This method takes XML in text format and uses the browser's XML parser to create a document.

oModel.setXML("<?xml version=\"1.0\"?><some><xml>data</xml></some>");

4. Usually, you load your data from the server using an HTTP-based service, so the loadData method provides an easy way to load XML data from the given URL:

oModel.loadData("data.xml");

For a complete listing of the available methods and parameters, see the API Reference.

Sorting and Filtering in a XML ModelWhen using an XML model, all data is available on the client. Sorting and filtering are implemented in JavaScript.

To define custom methods, set the fnCompare method on the Sorter object or the fnTest method on the Filter object after creating it.

1. To implement a filter:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 93

The fnTest method of the Filter gets the value to test as the only parameter and returns, whether the row with the given value should be filtered or not.

var oFilter = new sap.ui.model.Filter("property");oFilter.fnFilter = function(value) { return (value > 100);};

2. To implement a sorter:

The fnCompare method of the Sorter gets the two values to compare as parameters and returns -1, 0 or 1, dependent which of the two values should be ordered before the other.

var oSorter = new sap.ui.model.Sorter("property");oSorter.fnCompare = function(value1, value2) { if (value1 < value2) return -1; if (value1 == value2) return 0; if (value1 > value2) return 1;};

XML Namespace SupportThe XML model supports documents using XML namespaces.

For this purpose, you must declare namespaces using the setNameSpace method. The namespace prefixes do not necessarily need to be the same as in the XML document, they only used in the binding paths which are used to address nodes in the document.

Assumed this sample XML document:

<data xmlns="http://tempuri.org/base" xmlns:ext="http://tempuri.org/ext"> <ext:entry id="1" value="foo" /> <ext:entry id="1" value="foo" /></data>

The namespaces must be declared in the JavaScript like this, to be able to bind to them:

var oModel = new sap.ui.model.xml.XMLModel(oXMLDoc);oModel.setNameSpace("http://tempuri.org/base");oModel.setNameSpace("http://tempuri.org/ext", "e"); [...]oTable.bindRows("/e:entry");

Binding Path Syntax for XML ModelsXML differentiates between attributes and content, XML has no arrays and defines lists as multiple elements with the same name instead.

This makes data binding in XML models more difficult. For attributes, a special selector using the "@" character exists and "text()" can be used to reference the content text of an element. Lists are referenced by using the path to the multiple element.

NoteFor the XML model the root must not be included in the path.

#!xml<companies> <company name="Treefish Inc"> <info> <employees>3</employees> </info>

94 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

<contact phone="873">Barbara</contact> <contact phone="734">Gerry</contact> <contact phone="275">Susan</contact> </company></companies>

Absolute binding paths within this model:

/company/@name/company/info/employees

Relative binding paths within the /company context:

@nameinfo/employees/text()

Relative binding paths within an aggregation binding of /company/contact:

text()@phone

NoteIn a similar JSON model you would use /companies/company/locations as binding path for the locations collection. In an XML model the respective collection binding path is: /company/locations/location.

Implementing a Custom Model

To create a custom model implementation, proceed as follows:

1. Extend the Model class and specify the binding modes that the model should support (for example, two-way, one-way, one-time).

2. Extend the Binding class to suit your specific binding or reuse the existing specific binding implementations PropertyBinding, ListBinding, and/or TreeBinding.

3. To enable the filtering functionality, use the Filter class with FilterOperator enum in your binding implementation.

4. To enable the sorting functionality, use the Sorter class in your binding implementation.

You can find all necessary classes in the sap.ui.model namespace.

As a starting point, take a look at the JSONModel implementation in sap.ui.model.json.JSONModel.

Assigning the Model to the UI

Before you can bind controls to a model instance, you have to make it known to the framework. SAPUI5 provides a flexible and modularized concept in which you can not only define one model for your applications, but define different areas in your application with different models and assign single controls to a model. You can also define nested models, for example, a JSON model defined for the application and an OData model for a table control contained in the application.

In order to find the model it should bind to, the control looks up the parent hierarchy until it finds a control or UI area that has an assigned model. A control can only bind to one model, so if you have a container control with an

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 95

assigned model, all controls contained in this container can only see the local model of the container and are no longer able to bind to the global model.

Choose one of the following options:

○ You can define a global model that can be accessed by all controls from all UI areas by using the setModel method on the SAPUI5 core object. This is useful for simple form applications or demo applications.

sap.ui.getCore().setModel(oModel);

○ You can also define a specific model for sections within a UI area, for example, inside a panel or for a table control. In this case, you can use the setModel method available on any control:

var oTable = sap.ui.getCore().byId("table");oTable.setModel(oModel);

Defining a Binding Path

You use binding paths to address the different properties and lists contained in a model. The binding path defines how a specific node in the hierarchical data tree can be found. A binding path contains a number of name tokens, which are separated by a separator char. In all models provided by the framework, the separator char is the slash "/".

A binding path can either be absolute or relative: Absolute binding paths start with a slash, relative binding paths start with a name token and are resolved relative to the contet of the control that is bound.

A context exists either for each entry of the aggregation in case of aggregation binding or can be set explicitly for a control by using the setBindingContext method. Relative bindings without a defined context are resolved relative to the model root.

The syntax is specific to the respective model.

The syntax to define a binding path is different for each model:

○ JSON model: Implementing a JSON Model [page 85]○○○

Binding Controls to the Model

To retrieve data from the model for visualization in the UI, the controls have to be bound to the model, using a binding path as explained above. In general, the control itself, all properties of controls, and all multiple aggregations can be bound to a model.

Element binding allows to bind elements to a specific object in the model data, which will create a binding context and allow relative binding within the control and all of its children. This is especially helpful in master/detail scenarios.

96 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Property binding allows properties of the control to get automatically initialized and updated from model data. You can only bind control properties to model properties of a matching type, or you use a formatter function or datatype to convert the data as needed.

Aggregation binding can be used to automatically create child controls according to model data. This can be done either by cloning a template control, or by using a factory function. Aggregations can only be bound to lists defined in the model, that is, to arrays in a JSON model or a collection in the OData model.

Related Information

Binding Types [page 98]

Setting the Default Binding Mode

When a model instance is created, the instance has a default binding mode. You can overwrite this default setting.

1. To change the default binding mode directly after model creation, call the setDefaultBindingMode method on the model as follows:

var oModel = new sap.ui.model.json.JSONModel();oModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);

In this example, all new bindings for the model will have the one-way binding mode by default.2. You can, however, only set supported binding modes as default binding mode. You can check if a binding

mode is supported as follows:

var oModel = new sap.ui.model.json.JSONModel();if (oModel.isBindingModeSupported(sap.ui.model.BindingMode.OneTime)) { // true oModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneTime); }

Multimodel Support

You can set an additional model for an element or for the core by specifying a name for the model to identify it:

var oModel = new sap.ui.model.json.JSONModel();// define data for that modeloModel.setData({ test: "Test", enabled: true});

// define a name for that modelsap.ui.getCore().setModel(oModel, "myModel");

To create property bindings for this model call

oText.bindValue("myModel>/test").

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 97

You can also create aggregation bindings for this model by calling:

oListItem.bindProperty("text", "myModel>text");oComboBox.bindItems("myModel>/items", oListItem);

You specify the model name and following the > sign you specify the binding path to the values in the model that is to be bound.

NoteYou can create a model with an identifying name without first creating a model without a name.

1.1.3.4.3 Binding Types

The following sections introduce the data binding types provided by SAPUI5:

● Property Binding● Aggregation Binding● Element Binding

Property Binding

To define a property binding on a control, the following two options exist:

● In the settings object in the constructor of a control● Using the bindProperty method of a control

Once you have defined the property binding, the property is updated automatically every time the bound model property value is changed.

The most convenient way to define a property binding, which is sufficient in most cases, is to include the binding path within curly brackets as a string literal in the settings object:

var oTextField = new sap.ui.commons.TextField({ value: "{/company/name}"});

Alternatively, you can use an extended syntax for property bindings. This extended syntax allows you to define additional binding information to be contained in the settings object, such as a formatter function. In this case you use a JS object instead of a string literal. This must contain a path property containing the binding path and can contain additional properties:

var oTextField = new sap.ui.commons.TextField({ value: { path: "/company/name", mode: sap.ui.model.BindingMode.OneWay }});

98 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Depending on the use case, it can be useful to define the binding at a later time, using the bindProperty method:

oTextField.bindProperty("value", "/company/name");

This option also allows the use of the same object-literal as in the constructor to define the binding

oTextField.bindProperty("value", { path: "value", type: new sap.ui.model.type.Integer()});

Some controls offer convenience methods for the main properties of a control that are most likely to be bound by an application.

oTextField.bindValue("/company/name");

To remove a property binding, you can use the unbindProperty method. The property binding is removed automatically whenever a control is destroyed.

oTextField.unbindProperty("value");

For a complete list of supported parameters, see the API Reference.

Formatting Property Values

The values in the data are often represented in some internal format and need to be converted to an external format for visual representation. This is especially necessary for numbers, dates, and times with locale dependent external formats. SAPUI5 provides two different conversion options: Formatter functions allow one-way conversion only, while data types can also be used for two-way binding as they cannot only format, but also parse user input. You can choose freely for each binding, depending on your scenario.

The formatter function can either be passed as a third parameter to the bindProperty method, or contained in the binding info with the key "formatter". It has a single parameter value, which is the value which needs to be formatted to an external representation, and is executed as a member of the control, so can access additional control properties or model data.oTextField.bindProperty("value", "/company/title", function(sValue) { return sValue && sValue.toUpperCase();});

oControl = new sap.ui.commons.TextField({ value: { path:"/company/revenue", formatter: function(fValue) { if (fValue) { return "> " + Math.floor(fValue/1000000) + "M"; } return "0"; } }}) The formatter function, as it can contain any JavaScript, can not only be used for formatting a value, but can also do type conversion or calculate results from a given value, for example to show a special traffic light image depending on a boolean value:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 99

oImage.bindProperty("src", "/company/trusted", function(bValue) { return bValue ? "green.png" : "red.png";});

Using Data Types

The type system provides the possibility to format and parse data, as well as validating if the entered data is within defined constraints. You can define a type to be used for a property binding, by passing it as a third parameter in bindProperty or by adding it to the binding information with the key "type".

oTextField.bindProperty("value", "/company/title", new sap.ui.model.type.String());

oControl = new sap.ui.commons.TextField({ value: { path:"/company/revenue", type: new sap.ui.model.type.Float({ minFractionDigits: 2, maxFractionDigits: 2 }) }}) You can define custom types by inheriting from sap.ui.model.SimpleType and implementing the three methods formatValue, parseValue and validateValue. formatValue will be called whenever the value in the model is changed to convert it to the type of the control property it is bound to and may throw a FormatException. parseValue is called, whenever the user modified a value in the UI and the change is transported back into the model. It may throw a ParseException in case the value cannot be converted. In case of successful parsing validateValue is called to check additional constraints, like minimum or maximum value, and throws a ValidateException in case constraints are violated.

sap.ui.model.SimpleType.extend("sap.test.PLZ", { formatValue: function(oValue) { return oValue; }, parseValue: function(oValue) { return oValue; }, validateValue: function(oValue) { if (!/^(\d{5})?$/.test(oValue)) { throw new sap.ui.model.ValidateException("PLZ must have 5 digits!"); } }});

For more information, see Using the Data Binding Type System.

Binding Mode

By default, all bindings of a model instance have the default binding mode of the model. You can change this behavior. When creating a PropertyBinding, you can specify a different binding mode, which is then used exclusively for this specific binding. Of course, a binding can only have a supported binding mode of the model.

var oModel = new sap.ui.model.json.JSONModel();// default binding mode is Two Way

100 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

oModel.setData(myData);sap.ui.getCore().setModel(oModel);var oText = new sap.ui.commons.TextField();// bind value property one way only // propertyname, formatter function, binding modeoText.bindValue("/firstName", null, sap.ui.model.BindingMode.OneWay);oText.placeAt("target1");oText = new sap.ui.commons.TextField();// bind value property two way which is the defaultoText.bindValue("/firstName");oText.placeAt("target2");}

In the example above, two TextFields are created and their value property is bound to the same property in the model. The first TextField binding has a one-way binding mode, whereas the second TextField has the default binding mode of the model instance, which is two-way. So, when text is entered in the first TextField, the value will not be changed in the model. This happens only if text is entered in the second TextField. Then, of course, the value of the first TextField will be updated as it has a one-way binding, which means from model to view.

Aggregation Binding

You can define aggregation binding either in the settings object in the constructor or by calling the bindAggregation method. Aggregation binding requires the definition of a template, which is cloned for each bound entry of the list. For each clone that is created, the binding context is set to the respective list entry, so that all bindings of the template are resolved relative to the entry. The aggregated elements are destroyed and recreated whenever the bound list in the data model is changed.

Controls for the visualization of large data sets, for example Table or RowRepeater, only create clones for the currently visible entries and not for all list entries by using a custom updateAggregation method.

To bind an aggregation, you create a template or provide a factory function, which is then passed when defining the aggregation binding itself. In the settings object, this looks as follows:

var oItemTemplate = new sap.ui.core.ListItem({text:"{name}"});var oComboBox = new sap.ui.commons.ComboBox({ items: { path: "/company/contacts", template: oItemTemplate }});

You can also define the aggregation binding by using the bindAggregation method of a control:

oComboBox.bindAggregation("items", "/company/contacts", new sap.ui.core.ListItem({text:"{name}"}));

Some controls have a typed binding method for aggregations that are likely to be bound by the application:

oComboBox.bindItems("/company/contacts", oItemTemplate);

To remove an aggregation binding, you can use the unbindProperty method. The aggregation binding is then removed automatically whenever a control is destroyed.

oComboBox.unbindAggregation("items");

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 101

For more information, see the API Reference.

Using Template Controls

For structured data with list entries with the same properties using template controls within the aggregation binding is recommended. A template is not necessarily a single control as in the examples above, but can be a tree of controls. For each list entry, a deep clone of the template is created and added to the bound aggregation.

var oMatrixLayout = new sap.ui.commons.layout.MatrixLayout();

var oRowTemplate = new sap.ui.commons.layout.MatrixLayoutRow({ cells: [ new sap.ui.commons.layout.MatrixLayoutCell({ content: new sap.ui.commons.Label({text:"Name:"}) }), new sap.ui.commons.layout.MatrixLayoutCell({ content: new sap.ui.commons.TextView({text:"{name}"}) }) ]});

oMatrixLayout.bindAggregation("rows", "/company/contacts", oRowTemplate);

Using Factory Functions

The factory function is a more powerful approach for creating controls from model data. The factory function is called for each list entry to create the controls necessary to represent the current entry. The developer can decide, whether it is the same control with different properties or even a completely different control for each entry.

The factory function gets the parameters sId. These parameters must be used as they identify the created control and the context object oContext, which allows accessing data from the list entry. It returns an instance of sap.ui.core.Element.

oContainer.bindAggregation("content", "/company/properties", function(sId, oContext) { var value = oContext.getProperty("value"); switch(typeof value) { case "string": return new sap.ui.commons.TextField(sId, { value: { path: "value", type: new sap.ui.model.type.String(); } }); case "number": return new sap.ui.commons.TextField(sId, { value: { path: "value", type: new sap.ui.model.type.Float(); } }); case "boolean": return new sap.ui.commons.CheckBox(sId, { checked: {

102 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

path: "value" } }); }});

Initial Sorting and Filtering for Aggregation Binding

You can provide initial sorting and filtering when specifying the aggregation binding. Proceed as follows:

● Define a sorter and/or filters:

var oSorter = new sap.ui.model.Sorter("name", true); // sort descendingvar 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, "Paz");var oFilter3 = new sap.ui.model.Filter("name", sap.ui.model.FilterOperator.BT, "A","G"); // name between A and G

● Hand the sorter and/or filters to the aggregation binding:

var oComboBox = new sap.ui.commons.ComboBox({ items: {path:"/company/contacts", template:oItemTemplate, sorter:oSorter, filters:[oFilter1,oFilter2,oFilter3]}});

You can also use the other aggregation binding possibilities (for example bindAggregation, bindItems) and provide the sorter and filters as parameters.

Manual Sorting and Filtering for Aggregation Binding

To sort/filter data manually after the aggregation binding is complete you can do so by getting the corresponding binding and calling the sort/filter function:

var oSorter = new sap.ui.model.Sorter("name", true); // sort descendingvar 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, "Paz");var oFilter3 = new sap.ui.model.Filter("name", sap.ui.model.FilterOperator.BT, "A","G"); // name between A and G

// manual sortingoTable.getBinding("rows").sort(oSorter);

// manual filteringoTable.getBinding("rows").filter([oFilter1,oFilter2,oFilter3]);oComboBox.getBinding("items").filter([oFilter1,oFilter2,oFilter3]);

To get the binding of a control you have to know the name of the aggregation which is for example 'rows' for the table control.

For more information about the various sorting and filter methods and operators, see the documentation for Filter, Sorter, and Filter operations in the API Reference.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 103

Element Binding

Binding an element allows to set the binding context of the element to the object referenced by the given binding path. Thus, all relative bindings within the control and all of its children are resolved relative to this object. For server-side models, the element binding triggers the request to the server to load the referenced object in case it is not yet available on the client.

Element bindings can also be defined relatively. In case of relative element bindings, the binding context is updated when the parent binding context is changed.

To define an element binding, use the bindElement method on a control:

oControl.bindElement("/company");oControl.bindProperty("value", "name");

Element binding is especially interesting for containers or layouts containing many controls that are all visualizing properties of the same model object.

var oMatrixLayout = new sap.ui.commons.layout.MatrixLayout();oMatrixLayout.bindElement("/company");oMatrixLayout.createRow( new sap.ui.commons.Label({text: "Name:"}), new sap.ui.commons.TextField({value: "{name}"}));

oMatrixLayout.createRow( new sap.ui.commons.Label({text: "Revenue:"}), new sap.ui.commons.TextField({value: "{revenue}"}));oMatrixLayout.createRow( new sap.ui.commons.Label({text: "Employees:"}), new sap.ui.commons.TextField({value: "{employees}"}));

Setting a New Context for the Binding (Master Detail)

You create a new binding context for an element that is used to resolve bound properties or aggregations relative to the given path. You can use this method if the existing binding path changes or has not been provided before, for example in master detail scenarios.

Below is a simple example:

var data = {clients:[{firstName:"Donald", lastName:"Duck"}]};...// create and set model herevar oLabel = new sap.ui.commons.Label("myLabel");oLabel.bindProperty("text", "firstName");oLabel.bindElement("/clients/0");

The bindProperty method binds the text value of the label to the firstName property in the model. As the path to this property in the model is not set, this will not resolve. To resolve the binding, you use the bindElement method which creates a new context from the specified relative path.

To remove the current binding context, call the unbindElement method on the label. By this, all bindings now resolve relative to the parent context again.

104 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

You can also use the bindElement method in conjunction with aggregation binding:

var data = {clients:[ {firstName:"Donald", lastName:"Duck"}, items: [ {name: "iPhone"}, {name:"iPad"} ] } ]};...// create and set model herevar oLB = new sap.ui.commons.ListBox("myLb", {height:"100px"});var oItemTemplate = new sap.ui.core.ListItem(); oItemTemplate.bindProperty("text", "name");oLB.bindAggregation("items", "items", oItemTemplate);oLB.bindElement("/clients/0");

In this example, the ListBox is used to display the detailed data (items data) for a specified client. Another control can now be used to show the master data (client data) in the same way as in the first example with the label.

This example only works if the additional detailed data in the model which should be displayed in the ListBox (items in the example) is nested in the corresponding parent data (the client in the example). As you can see in the model, the items are contained in the client data.

You can also use a filtering function, for example in a table, to display detailed data for selected master data. In this case, nested data is not necessary in the model.

1.1.3.4.4 Using the Data Binding Type System

Data binding supports the definition of types which can be handed over when binding properties. These types define the data type for properties in the model. The values are then automatically formatted for display in the UI. In addition to this, the input values in UI controls are parsed and converted back to the defined type in the model. If an error occurs during formatting or parsing, the following exception occurs: sap.ui.model.FormatException / sap.ui.model.ParseException.

All types inherit from the abstract sap.ui.model.Type class. A subclass of this class is sap.ui.model.SimpleType. The currently available types inherit from SimpleType class.

You can generate the following parameters for each SimpleType in the constructor:

● format options: Format options define how a value is formatted and displayed in the UI.● constraints: Constraints are optional and define how an input value entered in the UI should look like.

During parsing the value is validated against these constraints. For example, a String type has a constraint for maxLength and minLength which are automatically validated when parsing the input values.

The following sections describe the available constraints and format options for each type.

Example: Using Data Types

The following example shows how to use data types:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 105

A sap.ui.model.type.Float type is created with the formatting options minimum/maximum fraction digits equals 2 and a maximum value constraint of 10:

// creating of a float type with 2 format options and one constraintvar oFloat = new sap.ui.model.type.Float( { minFractionDigits: 2, maxFractionDigits: 2 }, { maximum: 10 });

To use the defined data type for the binding, proceed as follows:

// specify the binding and the type directly in the control constructorvar oText = new sap.ui.commons.TextField({value: {path: "/sliderValue", type: oFloat}});// or alternatively do it afterwardsoText.bindValue("/sliderValue", oFloat);

Input parsing and output formatting are now carried out automatically. If, for example, the float value in the model is 2.3345, the text field displays the value 2.33. A user enters a value which is validated after user entry. To be valid, the entered value must be lower than 10.

Handling Wrong User Input

You can register a handler to validate, parse, and format issues by using the following functions of sap.ui.getCore():

● attachFormatError● attachParseError● attachValidationError● attachValidationSuccess

Simple Types

The following sections introduce the simple types that are currently available for data binding in SAPUI5.

NoteUse the following data types only with data binding.

● sap.ui.model.type.Integer● sap.ui.model.type.Float● sap.ui.model.type.String

106 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● sap.ui.model.type.Boolean● sap.ui.model.type.Date● sap.ui.model.type.Time● sap.ui.model.type.DateTime

The types use the below listed formatter classes. The formatters can, however, also be used standalone for formats, such as dates.

NoteThe formatter classes do not provide validation.

List of formatter classes:

● sap.ui.core.format.DateFormat● sap.ui.core.format.NumberFormat

sap.ui.model.type.Integer

The Integer type represents an integer value. The source value (value given in the model) must be given as a number and is transformed into the type of the bound control property:

● float: Value is rounded using Math.floor● integer: No transformation needed● string: Value is formatted or parsed according to the given output pattern

Examples how an Integer type can be initialized:

// The source value is given as Javascript number. Output is transformed into the type of the bound control property.// If this type is "string" (e.g. the value property of the TextField control) the used default output pattern parameters depend on locale and fixed settings.var oType = new sap.ui.model.type.Integer();

// The source value is given as Javascript number. Output is transformed into the type of the bound control property.// If this type is "string" (e.g. the value property of the TextField control) the given output pattern is used (parameters which are not specified are taken from the default pattern)

oType = new sap.ui.model.type.Integer({ minIntegerDigits: 1, // minimal number of non-fraction digits maxIntegerDigits: 99, // maximal number of non-fraction digits minFractionDigits: 0, // minimal number of fraction digits maxFractionDigits: 0, // maximal number of fraction digits groupingEnabled: false, // enable grouping (show the grouping separators) groupingSeparator: ",", // the used grouping separator decimalSeparator: "." // the used decimal separator});

The Integer type supports the following validation constraints:

● maximum● minimum

sap.ui.model.type.Float

The Float type represents a float value. The source value (value given in the model) must be given as a number and is transformed into the type of the bound control property:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 107

● float: No transformation needed● integer: Value is rounded using Math.floor● string: Value is formatted or parsed according to the given output pattern

Examples how a Float type can be initialized:

// The source value is given as Javascript number. Output is transformed into the type of the bound control property.// If this type is "string" (e.g. the value property of the TextField control) the used default output pattern parameters depend on locale and fixed settings.

var oType = new sap.ui.model.type.Float();

// The source value is given as Javascript number. Output is transformed into the type of the bound control property.// If this type is "string" (e.g. the value property of the TextField control) the given output pattern is used (parameters which are not specified are taken from the default pattern)

oType = new sap.ui.model.type.Float({ minIntegerDigits: 1, // minimal number of non-fraction digits maxIntegerDigits: 99, // maximal number of non-fraction digits minFractionDigits: 0, // minimal number of fraction digits maxFractionDigits: 99, // maximal number of fraction digits groupingEnabled: true, // enable grouping (show the grouping separators) groupingSeparator: ",", // the used grouping separator decimalSeparator: "." // the used decimal separator});

The Float type supports the following validation constraints:

● maximum● minimum

sap.ui.model.type.String

The String type represents a string. The source value (value given in the model) must be given as a number and is transformed into the type of the bound control property:

● string: No transformation needed● integer/float: String is parsed accordingly● boolean: "true" or "X" are interpreted as true, false, and " " as false

The string type does not have any format options.

Example how a String type can be initialized:

// The source value is given as string. The length of the string must not greater than 5.var oType = new sap.ui.model.type.String(null, {maxLength: 5});

The String type supports the following validation constraints:

● maxLength (expects an integer number)● minLength (expects an integer number)● startsWith (expects a string)● startsWithIgnoreCase (expects a string)● endsWith (expects a string)● endsWithIgnoreCase (expects a string)

108 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● contains (expects a string)● equals (expects a string)● search (expects a regular expression)

sap.ui.model.type.Boolean

The Boolean type represents a string. The source value (value given in the model) must be given as boolean and is transformed into the type of the bound control property:

● boolean: No transformation needed● string: "true" or "X" are interpreted as true, "false" and "" as false

The Boolean type has no format or validation constraint options.

Example how a Boolean type can be initialized:

// The source value is given as boolean.var oType = new sap.ui.model.type.Boolean();

sap.ui.model.type.Date

The Date type represents a date (without time). It transforms a source value (given value in the model) into a formatted date string and the other way round.

The format patterns must be defined in LDML Date Format notation. For the output, the use of a style ("short, "medium", "long" or "full") instead of a pattern is preferred, as it will automatically use a locale-dependent date pattern.

Examples how a Date type can be initialized:

// The source value is given as Javascript Date object. The used output pattern depends on the locale settings (default).var oType = new sap.ui.model.type.Date();// The source value is given as Javascript Date object. The used output pattern is "yy-MM-dd": e.g. 09-11-27oType = new sap.ui.model.type.Date({pattern: "yy-MM-dd"}); // The source value is given as string in "yyyy/MM/dd" format. The used output style is "long". The styles are language dependent.// The following styles are possible: short, medium (default), long, full// This usecase might be the common one.oType = new sap.ui.model.type.Date({source: {pattern: "yyyy/MM/dd"}, style: "long"}); // The source value is given as string in "yyyy/MM/dd" format. The used output pattern is "EEEE, MMMM d, yyyy": e.g. Saturday, August 22, 2043oType = new sap.ui.model.type.Date({source: {pattern: "yyyy/MM/dd"}, pattern: "EEEE, MMMM d, yyyy"}); // The source value is given as timestamp. The used output pattern is "dd.MM.yyyy": e.g. 22.12.2010oType = new sap.ui.model.type.Date({source: {pattern: "timestamp"}, pattern: "dd.MM.yyyy"}); // The source value is given as string. The used input pattern depends on the locale settings (default). The used output pattern is "dd '|' MM '|' yyyy": e.g. 22 | 12 | 2010oType = new sap.ui.model.type.Date({source: {}, pattern: "dd.MM.yyyy"});

The Date type supports the following validation constraints:

● maximum (expects an date presented in the source-pattern format)● minimum (expects an date presented in the source-pattern format)

sap.ui.model.type.Time

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 109

The Time type represents a time (without date). It transforms a source value (given value in the model) into a formatted time string and the other way round.

The format patterns must be defined in LDML Date Format notation. For the output, the use of a style ("short, "medium", "long" or "full") instead of a pattern is preferred, as it will automatically use a locale dependent time pattern.

Examples how a Time type can be initialized:

// The source value is given as Javascript Date object. The used output pattern depends on the locale settings (default).var oType = new sap.ui.model.type.Time();// The source value is given as Javascript Date object. The used output pattern is "hh-mm-ss": e.g. 09-11-27oType = new sap.ui.model.type.Time({pattern: "hh-mm-ss"}); // The source value is given as string in "hh-mm-ss" format. The used output style is "short". The styles are language dependent.// The following styles are possible: short, medium (default), long, full// This usecase might be the common one.oType = new sap.ui.model.type.Date({source: {pattern: "hh-mm-ss"}, style: "short"}); // The source value is given as string in "hh/mm/ss/SSS" format. The used output pattern is "HH:mm:ss '+' SSS 'ms'": e.g. 18:48:48 + 374 msoType = new sap.ui.model.type.Time({source: {pattern: "hh/mm/ss/SSS"}, pattern: "HH:mm:ss '+' SSS 'ms'"}); // The source value is given as timestamp. The used output pattern is "HH 'Hours' mm 'Minutes'": e.g. 18 Hours 48 MinutesoType = new sap.ui.model.type.Time({source: {pattern: "timestamp"}, pattern: "HH 'Hours' mm 'Minutes'"}); // The source value is given as string. The used input pattern depends on the locale settings (default). The used output pattern is "hh:mm a": e.g. 06:48 PMoType = new sap.ui.model.type.Time({source: {}, pattern: "hh:mm a"});

The Time type supports the following validation constraints:

● maximum (expects an time presented in the source-pattern format)● minimum (expects an time presented in the source-pattern format)

sap.ui.model.type.DateTime

The DateTime type represents an exact point of time (date and time). It transforms a source value (given value in the model) into a formatted date+time string and the other way round.

The format patterns must be defined in LDML Date Format notation. For the output, the use of a style ("short, "medium", "long" or "full") instead of a pattern is preferred, as it will automatically use a locale-dependent date and time pattern.

CautionWhen talking about exact points in time, time zones are imported. The formatted output of the DateTime type currently shows the "local" time which equals the time settings of the machine on which the browser runs. If the source value is given as a Javascript Date object or as a timestamp, the exact moment is sufficiently defined. For string source values this value is interpreted in "local" time if it does not explicitly have a time zone. Currently, all accepted time zone notations must be based on GMT/UTC.

Examples how a DateTime type can be initialized:

// The source value is given as Javascript Date object. The used output pattern depends on the locale settings (default).var oType = new sap.ui.model.type.DateTime();

110 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

// The source value is given as Javascript Date object. The used output pattern is "yyyy/MM/dd HH:mm:ss": e.g. 2011/04/11 09:11:27oType = new sap.ui.model.type.DateTime({pattern: "yyyy/MM/dd HH:mm:ss"}); // The source value is given as string in "yyyy/MM/dd HH:mm:ss" format. The used output style is "full". The styles are language dependent.// The following styles are possible: short, medium (default), long, full// This usecase might be the common one.oType = new sap.ui.model.type.Date({source: {pattern: "yyyy/MM/dd HH:mm:ss"}, style: "full"}); // The source value is given as string in "dd.MM.yyyy HH:mm:ss" format (no timezone given). The used output pattern is "MMMM d, yyyy, HH:mm:ss.SSS": e.g. August 22, 2043, 18:48:48.374oType = new sap.ui.model.type.DateTime({source: {pattern: "dd.MM.yyyy HH:mm:ss"}, pattern: "MMMM d, yyyy, HH:mm:ss.SSS"});// The source value is given as timestamp. The used output pattern is "dd.MM.yyyy HH:mm": e.g. 22.12.2010 13:15oType = new sap.ui.model.type.DateTime({source: {pattern: "timestamp"}, pattern: "dd.MMM.yyyy HH:mm"}); // The source value is given as string. The used input pattern depends on the locale settings (default). The used output pattern is "hh-mm-ss '/' yy-MM-dd": e.g. 06-48-48 / 43-08-22oType = new sap.ui.model.type.DateTime({source: {}, pattern: "hh-mm-ss '/' yy-MM-dd"}); // The source value is given as string in "dd.MM.yyyy HH:mm:ss X" format (timezone is defined in ISO8601 format, e.g. "+02:00"). The used output pattern depends on the locale settings (default).oType = new sap.ui.model.type.DateTime({source: {pattern: "dd.MM.yyyy HH:mm:ss X"}});// The source value is given as string in "dd.MM.yyyy HH:mm:ss Z" format (timezone is defined in RFC822 format, e.g. "+0200"). The used output pattern depends on the locale settings (default).oType = new sap.ui.model.type.DateTime({source: {pattern: "dd.MM.yyyy HH:mm:ss Z"}});// The source value is given as string in "dd.MM.yyyy HH:mm:ss z" format (timezone is currently defined as e.g. "GMT+02:00", "UTC+02:00", "UT+02:00" or "Z" (shortcut for "UTC+00:00")).// The used output pattern depends on the locale settings (default).oType = new sap.ui.model.type.DateTime({source: {pattern: "dd.MM.yyyy HH:mm:ss z"}});

The DateTime type supports the following validation constraints:

● maximum (expects an dateTime presented in the source-pattern format)● minimum (expects an dateTime presented in the source-pattern format)

Data Types for Use Without Data Binding

The simple types in the previous sections are not intended to be used without data binding. But they use formatter classes, which can also be used standalone to format, for example, dates. The formatter classes do not provide validation.

You can use the following formatter classes:

● sap.ui.core.format.DateFormat● sap.ui.core.format.NumberFormat

sap.ui.core.format.DateFormat

The DateFormat class can be used to parse a string representing a date, time or datetime into a JavaScript date object and vice versa (also known as format).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 111

The format pattern must be defined in LDML date format notation. The following options are available:

● style: Can be "short", "medium", "long" or "full" and will use a locale dependent pattern● pattern: A date pattern in LDML Date Format notation

In case both, style and pattern, are defined, the pattern is used and the style ignored.

Example how the DateFormat class can be used:

jQuery.sap.require("sap.ui.core.format.DateFormat");var oDateFormat = sap.ui.core.format.DateFormat.getDateTimeInstance({pattern: "dd/MM/yyyy HH:mm"}); //Returns a DateFormat instance for date and time//var oDateFormat = sap.ui.core.format.DateFormat.getInstance({pattern: "dd/MM/yyyy"}); //Returns a DateFormat instance for date//var oDateFormat = sap.ui.core.format.DateFormat.getTimeInstance({pattern: "HH:mm"}); //Returns a DateFormat instance for time

var oField = new sap.ui.commons.TextField();oField.setValue(oDateFormat.format(oDate)); // Set the formatted value on the text fieldoField.attachChange(function(){

//Parse the user input oDate = oDateFormat.parse(oField.getValue());});

sap.ui.core.format.NumberFormat

The NumberFormat class can be used to parse a string representing a number (float or integer) into a Javascript number and vice versa (also known as format). The following format options are possible. For parameters which are not specified default values according to the type are used:

● minIntegerDigits: minimal number of non-fraction digits● maxIntegerDigits: maximal number of non-fraction digits● minFractionDigits: minimal number of fraction digits● maxFractionDigits: maximal number of fraction digits● groupingEnabled: enable grouping (show the grouping separators)● groupingSeparator: used grouping separator● decimalSeparator: used decimal separator

Example how the NumberFormat class can be used:

var fValue = 20001000.563; jQuery.sap.require("sap.ui.core.format.NumberFormat");var oNumberFormat = sap.ui.core.format.NumberFormat.getFloatInstance({ maxFractionDigits: 2, groupingEnabled: true, groupingSeparator: ",", decimalSeparator: "."}); //Returns a NumberFormat instance for float/*var oNumberFormat = sap.ui.core.format.NumberFormat.getIntegerInstance({ maxFractionDigits: 0, groupingEnabled: false}); //Returns a NumberFormat instance for integer*/

var oField = new sap.ui.commons.TextField();oField.setValue(oNumberFormat.format(fValue)); // Set the formatted value on the text fieldoField.attachChange(function(){ //Parse the user input

112 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

fValue = oNumberFormat.parse(oField.getValue()); alert(fValue);});

1.1.3.4.5 Calculated Fields for Data Binding

The calculated fields feature enables the binding of multiple properties in different models to a single property of a control. For example, the value property of a text field may be bound to a property firstName and a property lastName in a model. The application can access these values in a formatter function and can decide how they should be processed or combined together. If no formatter function is specified, the values are joined together by default. You can use the useRawValues property to specify if the parameter values in the formatter function are formatted according to the type of the property or not.

The multiple property bindings are stored in a CompositeBinding and can be accessed by calling the getBindings function. You can access the composite binding, for example, by using the getBinding('value') function of the control. The composite binding has no path, model, context, and type because it contains multiple property bindings containing the necessary information. A composite binding may, for example, store two property bindings which belong to different models and have different types.

If you have specified a formatter function, it is also available in the composite binding.

NoteCurrently, calculated fields work only from model to view, read only, and the values can be accessed via a formatter function.

There are several options to create multiple bindings for a control. The syntax is very similar to the normal single binding declaration.

Each binding is created by the specified parts and assigned information. A part must contain the path to the property in the model and may contain additional information for the binding, for example a type. If multiple parts exist, the binding mode is automatically set to one-way binding.

Constructor Declaration

1. Use binding objects to add additional parameters, for example the type:

oTxt = new sap.ui.commons.TextField({ value: { parts: [ {path: "/firstName", type: new sap.ui.model.type.String()}, {path: "/lastName"}, {path: "myModel2>/amount", type: new sap.ui.model.type.Float()} // path to property in another model ] }});

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 113

2. Use strings which only take the path:

oTxt = new sap.ui.commons.TextField({ value: { parts: [ "/firstName", "/lastName", "myModel2>/fraud" // path to property in another model ] }});

Bind Property Declaration

1. Use binding objects to add additional parameters, for example the type:

oTxt.bindValue({ parts: [ {path: "/firstName", type: new sap.ui.model.type.String()}, {path: "/lastName"} ]});

2. Use strings which only take the path:

oTxt.bindValue({ parts: [ "/firstName", "/lastName" ]});

These samples also work with a relative binding path, when you use them as a template in an aggregation binding.

Custom Formatter Functions

The examples for constructor declaration and bind property declaration (see Calculated Fields for Data Binding) do not contain a formatter function. In this case, all values of the various parts are joined together as a string with a space seperator. To specify your own formatter, proceed as shown in the following example:

oTxt.bindValue({ parts: [ {path: "/firstName", type: new sap.ui.model.type.String()}, {path: "/lastName", type: new sap.ui.model.type.String()}, {path: "/amount", type: new sap.ui.model.type.Float()}, {path: "/currency", type: new sap.ui.model.type.String()} ], formatter: function(firstName, lastName, amount, currency){ // all parameters are strings if (firstName && lastName) { return "Dear " + firstName + " " + lastName + ". Your current balance is: " + amount + " " + currency; } else { return null; }

114 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}});

The values provided in the parameters of the formatter function are already formatted to the output type of the control, which is a string in this case (that is, the value property of text field is a string).

Custom Formatter Function with Raw Values

If you do not want the provided values in the formatter function being already formatted according to their type, you can set a flag to get the raw unformatted values. These values are also stored in the model. In this case, the types of the parts are ignored:

oTxt.bindValue({ parts: [ {path: "/firstName", type: new sap.ui.model.type.String()}, {path: "/lastName", type: new sap.ui.model.type.String()}, {path: "/amount", type: new sap.ui.model.type.Float()}, {path: "/model2>debts", type: new sap.ui.model.type.Float()} ], formatter: function(firstName, lastName, amount, debt){ // string, string, float, float if (firstName && lastName) { return "Dear " + firstName + " " + lastName + ". Your current balance is: " + (amount - debts); } else { return null; } }, useRawValues : true});

1.1.3.5 Implementing Views

This section provides information on how to implement functions depending on the view type.

Related Information

Namespaces in XML Views [page 116]

Aggregation Handling in XML Views [page 116]

Using Native HTML in XML Views [page 117]The use of native HTML depends on the XHTML feature set.

Using CSS Style Sheets in XML Views [page 118]You include style sheets like plain HTML. You can add further CSS classes to SAPUI5 controls by using the class attribute.

Handling Events in XML Views [page 118]

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 115

Event handlers are used as attributes. The attribute name is the event name, such as "press" for a button, and the attribute value as event handler name. The event handler must be defined as a function in the view's controller.

Handling Events in JSON Views [page 118]Event handlers are used as attributes with the attribute name as event name like "press" for a button and the attribute value as event handler name. The event handler must be defined as a function in the view's controller.

Instantiating Views [page 119]You use the factory method sap.ui.view to instantiate views.

1.1.3.5.1 Namespaces in XML Views

Analogous to generic XML mapping features, the names of SAPUI5 control libraries are mapped to XML namespaces. You can choose any of the required namespaces as default and, thus, the respective control tags do not need a prefix.

The <View> tag is required and in the example above, the core namespace is defined in the first line. Of course you can define any name. To keep the tag names shorter, for example, you can also use "c" instead of "core".

NoteIf controls are located in a subpackage of a control library, for example sap.ui.commons.layout.MatrixLayout, they must have their own XML namespace:

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:layout="sap.ui.commons.layout"> <layout:MatrixLayout> ...

1.1.3.5.2 Aggregation Handling in XML Views

You can simply add child controls as child tags, as shown in the example above where a <Button> tag is added to a <Panel> tag.

Some controls have more than one content area, for example the shell control that has the main content area, a pane bar, a headerItems aggregation, worksetItems, and so on. Hence, an aggregation tag usually serves as direct child of a container and contains children. It is only possible to directly add children as shown in the example above if the container control has marked one of the child aggregations as default.

Some containers may not have default content, for example, the splitter container has two equally important content areas.

NoteThe framework supports you by issuing error message in case of errors in the aggregation handling in XML views.

You fill aggregations as shown in the following example.

116 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteThe namespace of the parent control tag and the aggregation tag must be the same.

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core"> <Panel> <content> <!-- this is the general way of adding children: use the aggregation name --> <Image src="http://www.sap.com/global/ui/images/global/sap-logo.png"/> <Button text="Press Me"/> </content> </Panel><core:View>

1.1.3.5.3 Using Native HTML in XML Views

The use of native HTML depends on the XHTML feature set.

When mixing XHTML and SAPUI5 controls, observe the following rules:

● XHTML elements can be used instead of the SAPUI5 type control, for example, in the root of an XML view or in the content aggregation of a layout container.

● When embedding XHTML in an aggregation of a SAPUI5 control, the XHTML must not consist of a single text node. The topmost node of an embedded XHTML tree must be an XHTML element. Embedding pure text into an aggregation is not supported.

● The XHTML nodes are converted 1:1 to HTML, the XMLView does not deal with any differences between XHTML and HTML (for example rewriting and auto-closing tags)

● The created HTML DOM nodes are preserved during re-rendering of an XML view: Modifications to the DOM are not lost.

NoteAs an alternative to embedding XHTML, you can use the sap.ui.core.HTML control. As this requires content encoding it is, however, less convenient.

To mix SAPUI5 controls with native XHTML, you only need the XHTML namespace to use (X)HTML:

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml"> <Panel> <Button text="Press Me. I am a SAPUI5 Button"/> <html:button>No, press me. I am native HTML Button.</html:button> </Panel><core:View>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 117

1.1.3.5.4 Using CSS Style Sheets in XML Views

You include style sheets like plain HTML. You can add further CSS classes to SAPUI5 controls by using the class attribute.

The effect is the same as calling myButton.addStyleClass(...).

TipWe recommend to carefully choose the elements that you style as the CSS always affects the whole page and is not restricted to the view.

To add a style sheet, add the style definition.To add a style class and define a button that uses it, add the following coding:

<core:View controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml"> <html:style> .mySuperRedButton { color: red; } </html:style> <Panel> <Button class="mySuperRedButton" text="Press Me"/> </Panel><core:View>

1.1.3.5.5 Handling Events in XML Views

Event handlers are used as attributes. The attribute name is the event name, such as "press" for a button, and the attribute value as event handler name. The event handler must be defined as a function in the view's controller.

To attach en event handler in a XML view, insert the following declaration: ... <Button text="Press Me" press="doSomething"/> ...The method controller.doSomething() is executed when the button is pressed.

1.1.3.5.6 Handling Events in JSON Views

Event handlers are used as attributes with the attribute name as event name like "press" for a button and the attribute value as event handler name. The event handler must be defined as a function in the view's controller.

The following declaration causes controller.doSomething() to be executed when the button is pressed:

... { "Type":"sap.ui.commons.Button", "id":"MyButton", "text":"Press Me", "press":"doSomething"

118 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}...

1.1.3.5.7 Instantiating Views

You use the factory method sap.ui.view to instantiate views.

To pass required information for the instantiation, use an object with the following properties:a) type: The type can be JSON, JS, XML or HTML. All possible types are declared in the enumeration

sap.ui.core.mvc.ViewType.b) viewName: View name corresponding to the module conceptc) viewContent: Only relevant for XML views and JSON views. Defines the XML or JSON string

representation of the view definition. If viewName and viewContent are given, the viewName property is used to load the view definition.

d) Controller: Any controller instance; the given controller instance overrides the controller defined in the view definition

e) viewData: Only used for JS views; this property contains user-specific data that is available during the whole lifecycle of the view and the controller

... var myController = sap.ui.controller("my.own.controller"); var myView = sap.ui.view({ type: sap.ui.core.mvc.ViewType.XML, viewName: "my.own.view", controller: myController });...

All regular properties of a view (control) can be passed to the object as usual.

1.1.3.6 Custom Data - Attaching Data Objects to Controls

To attach data to SAPUI5 controls, the method data() has been added to the base class sap.ui.core.Element. You can use the method to set and get data. The API is equivalent to jQuery.data().

You can also use the following other possibilities to attach data to SAPUI5 controls:

● Attaching data declaratively in XML views and JSON views● Using data binding● For strings only: Writing data to the HTML DOM as "data-*" attribute.

Setting and Retrieving Data

To set and retrieve data, use the following code:

myButton.data("myData", "Hello"); // attach some data to the Button

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 119

alert(myButton.data("myData"); // alerts "Hello"

var dataObject = myButton.data(); // a JS object containing ALL dataalert(dataObject.myData); // alerts "Hello"

Binding Data: Use in a List Binding

For list bindings, use the following code:

// create a JSONModel, fill in the data and bind the ListBox to this model

var oModel = new sap.ui.model.json.JSONModel();oModel.setData(aData); // aData is a data array consisting of elements like {question:"Some question?",answer:"Some answer!"}var ctrl = new sap.ui.commons.ListBox({select:giveAnswer}); // method giveAnswer() retrieves the custom data from the selected ListItemctrl.setModel(oModel);

// create an item template and bind the question data to the "text" property

var oItemTemplate = new sap.ui.core.ListItem();oItemTemplate.bindProperty("text", "question");

// create a CustomData template, set its key to "answer" and bind its value to the answer data

var oDataTemplate = new sap.ui.core.CustomData({key:"answer"});oDataTemplate.bindProperty("value", "answer");

// add the CustomData template to the item template

oItemTemplate.addCustomData(oDataTemplate);

// bind the items to the "questions" (which is the name of the data array)

ctrl.bindAggregation("items", "questions", oItemTemplate);

You can find a productive example in the SAPUI5 test suite by searching for CustomData in sap.ui.core.

Use in XML Views

In XML views, CustomData objects can be written as normal aggregated objects. However, to reduce the amount of code and improve the readability, a shortcut notation has been introduced: You can directly write the data attributes into the control tags. You just need to use the following namespace for these attributes: myNamespace="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1.

This namespace is intentionally different and more formal than the existing MVC namespaces which will also be adapted to this more formal naming scheme.

Use without Data Binding

120 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The following example shows how you attach the string "just great" to a button:

#!xml

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.ui.commons" controllerName="my.own.controller" xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"> <Button id="myBtn" text="Click to show stored coordinates data" app:mySuperExtraData="just great" press="alertCoordinates"></Button></core:View>

The string is returned at runtime by calling button.data("mySuperExtraData").

Use with Data Binding

You can use data binding with the following notation:

#!xml

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.ui.commons" controllerName="my.own.controller" xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"> <Button id="myBtn" text="Click to show stored coordinates data" app:coords="{data}" press="alertCoordinates"></Button></core:View>

Use in JSON Views

To add custom data to an element in a JSON view, add the following code to the element properties (these examples include data binding):

customData: { Type:"sap.ui.core.CustomData", key:"coords", value:"{data}" // bind custom data }

To add multiple data elements, use an array:

customData: [{ Type:"sap.ui.core.CustomData", key:"coords", value:"{data}" // bind custom data }, { Type:"sap.ui.core.CustomData", key:"coords", value:"{data}" // bind custom data }]

In context, this looks as follows:

var json = { Type: "sap.ui.core.JSONView", controllerName:"my.own.controller", content: [{

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 121

Type:"sap.ui.commons.Panel", content:[{ Type:"sap.ui.commons.Button", text:"{actionName}", press: "doSomething", customData: { Type:"sap.ui.core.CustomData", key:"coords", value:"{data}" // bind custom data } }] }] };

1.1.3.6.1 Writing Data to the HTML DOM as DATA-* Attribute

It can be useful to write the custom data to the HTML DOM, for example to generate markers in the HTML from data binding which then can be used for data-dependent styling, or to create stable anchors in the HTML which can be used for automated tests.

A "data-" prefix is added to the key and the result is then written as attribute into the root HTML element of the control. The CustomData value is written as attribute value.

This only works when the key is a valid HTML ID and the value is a string (otherwise an error is logged). Note that HTML attribute names are case-insensitive and browsers may convert the key to lowercase.

NoteDo not write too much data into DOM.

In JavaScript the flag can be set like this:

myButton.data("mydata", "Hello", true); // attach some data to the Button and mark it as "write to HTML"

In XMLViews the aggregation has currently to be written in expanded notation to set the writeToDom flag:

<Button ... > <customData> <core:CustomData key="mydata" value="Hello" writeToDom="true" /> </customData></Button>

Resulting HTML:

<button ... data-myData="Hello" ... >

Now CSS can use attribute selectors to check presence or the value of the custom data attribute:

button[data-mydata="Hello"] { border: 3px solid red !important; }

122 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.7 Declarative Support

The SAPUI5 library can be extended to support declarative programming which allows you to define the UI within the HTML document as elements. For this, a plugin (sap.ui.core.plugin.DeclarativeSupport) can be included either as required or marked as a module in the initial bootstrap script tag. The plugin parses the document and converts its tags with special attributes into SAPUI5 controls.

Declarative support is aware of properties, associations, events, and aggregations in a SAPUI5 control manner. This means that you can specify them within the markup of the HTML document either as data attributes or as child elements.

The following sections provide an overview of the declarative support and introduce the use of declarative support in SAPUI5.

Example

The following example shows the concept by combining a sap.ui.commons.TextField with a sap.ui.commons.Button control. When you click the button, the value of the text field is displayed in an alert box:

<!Doctype HTML><html> <title>Declarative Programming for SAPUI5 - sample01</title>

<script id="sap-ui-bootstrap" type="text/javascript" src="http://veui5infra.dhcp.wdf.sap.corp:8080/sapui5/resources/sap-ui-core.js" data-sap-ui-theme="sap_platinum" data-sap-ui-libs="sap.ui.commons" data-sap-ui-modules="sap.ui.core.plugin.DeclarativeSupport" > </script>

</head><body class="sapUiBody">

<div data-sap-ui-type="sap.ui.commons.TextField" id="message" class="my-button" data-value="Hello World"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="Click me!" data-press="handlePress"></div>

</body></html>

Summary: Attributes Used by Declarative Support

The table summarizes the attributes used by declarative support and gives examples.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 123

Attribute Description Example

data-sap-ui-type Type of control <div data-sap-ui-type="sap.ui.commons.Button"></div>

data-sap-ui-aggregation Defines the aggregation that shall be used for the element or child element

<div data-sap-ui-type="sap.ui.commons.Panel"><div data-sap-ui-aggregation="title" data-sap-ui-type="sap.ui.commons.Title" data-text="My Panel"></div></div>

data-sap-ui.default-aggregation

Sets or overrides the default aggregation of a control

<div data-sap-ui-type="sap.ui.commons.Panel" data-sap-ui-default-aggregation="title"><div data-sap-ui-type="sap.ui.commons.Title" data-text="My Panel"></div></div>

id Defines the ID property of a control <div data-sap-ui-type="sap.ui.commons.Button" id="myButton"></div>

class Adds a style class to the control <div data-sap-ui-type="sap.ui.commons.Button" class="myButton"></div>

1.1.3.7.1 Enabling Declarative Support

To use declarative support you need to enable the declarative support in your HTML document by adding an attribute to the SAPUI5 bootstrap script tag. This is done as follows:

data-sap-ui-modules="sap.ui.core.plugin.DeclarativeSupport"

SAPUI5 then requires (loads) the plugin sap.ui.core.plugin.DeclarativeSupport. When started, the plugin parses and enhances special HTML tags in the HTML document. The complete bootstrap script tag for SAPUI5 (based on a CDN version) looks as follows:

<script id="sap-ui-bootstrap" type="text/javascript" src="http://veui5infra.dhcp.wdf.sap.corp:8080/sapui5/resources/sap-ui-core.js" data-sap-ui-theme="sap_platinum" data-sap-ui-libs="sap.ui.commons" data-sap-ui-modules="sap.ui.core.plugin.DeclarativeSupport" ></script>

124 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.7.2 Defining Controls

After you have enabled the declarative support, define controls in your HTML document as HTML tags with the following data attribute:

data-sap-ui-type="sap.ui.commons.Button"

This data attribute defines the SAPUI5 control that should be rendered in the HTML tag by using the HTML tag as its UI area. Rendering a button in the body of an HTML document without setting any property, association, event, or aggregation looks as follows:

<body> <div data-sap-ui-type="sap.ui.commons.Button"></div></body>

NoteMake sure that you close the tags properly. HTML5 does not support self-closing tags.

NoteAll attributes used to define properties, associations, events, or aggregations are data attributes except for attributes that exist in HTML, for example id or class. Data attributes are prefixed with data-*, for example data-text.

1.1.3.7.3 Declarative Support: Properties

To set a property, for example for a button, you define the property as a data attribute of the corresponding HTML tag. To add text to the button, add the attribute data-text to its HTML tag:

<div data-sap-ui-type="sap.ui.commons.Button" data-text="HelloWorld"></div>

NoteTo define a property with upper case characters, you have to "escape" them with a dash character, similar to CSS attributes. The following code gives an example:

<div data-sap-ui-type="sap.ui.commons.ApplicationHeader" data-display-logoff="false" data-display-welcome="false"></div>

As the name of the attributes of HTML tags are case-insensitive, the properties displayLogoff and displayWelcome of the ApplicationHeader control have to be "escaped" as data-display-logoff and data-display-welcome for the name of the attributes of the HTML tag. Keep this in mind when matching properties, associations ,or events as an attribute of the HTML tag.

The id attribute defines the ID of a control:

<div data-sap-ui-type="sap.ui.commons.Button" id="myButton"></div>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 125

To add a CSS class to the control, use the class attribute:

<div data-sap-ui-type="sap.ui.commons.Button" class="my-button"></div>

1.1.3.7.4 Declarative Support: Associations

An association is defined as a data attribute of the HTML tag. Instead of passing the reference to another control you define the ID of another control. The following code gives an example:

<div data-sap-ui-type="sap.ui.commons.Label" data-text="Message:" data-label-for="message"></div><div data-sap-ui-type="sap.ui.commons.TextField" id="message"></div>

The code snippet defines the link between Label and TextField by using the ID of TextField as a value for the data-label-for attribute of the Label.

1.1.3.7.5 Declarative Support: Events

The value of the event data attribute contains the name of a JavaScript function which will be used as callback once the event has been triggered. The following code snippet gives an example how a change of TextField results in an alert with its new value when the focus is lost:

<script> function handleChange (oEvent) { alert (oEvent.getSource().getValue()); }</script>

<div data-sap-ui-type="sap.ui.commons.TextField" data-value="Change me!" data-change="handleChange"></div>

Currently, SAPUI5 only supports to specify the name of a callback function. You can define callback functions within any class, see the following code example:

<div data-sap-ui-type="sap.ui.commons.TextField" data-value="Change me!" data-change= "my.company.MyClass.handleChange"></div>

1.1.3.7.6 Declarative Support: Aggregations

Agrregation support is required to allow nested controls for layout containers and/or add elements to a control, for example, for ComboBox.

126 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

SAPUI5 uses the control's default aggregation as default. If, for example, the panel control has the default aggregation content, all child elements of the data-sap-ui-type="sap.ui.commons.Panel" element are added to this aggregation:

<div data-sap-ui-type="sap.ui.commons.Panel"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 1"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 2"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 3"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 4"></div></div>

The markup in the example above generates an instance of the sap.ui.commons.Panel control and adds implicit four buttons to the default aggregation content of the control.

You can also explicitly declare an aggregation. In general, an explicit aggregation is expressed with a meta HTML tag between the parent controls HTML tag and the HTML tags of the children. The following code adds four buttons explicitly to the "content" aggregation of the declared panel:

<div data-sap-ui-type="sap.ui.commons.Panel"> <div data-sap-ui-aggregation="content"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 1"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 2"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 3"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 4"></div> </div></div>

For aggregations with the cardinality "0..1" the "data-sap-ui-aggregation" attribute can be written directly to the control tag:

<div data-sap-ui-type="sap.ui.commons.Panel"> <div data-sap-ui-aggregation="title" div data-sap-ui-type="sap.ui.commons.Title" data-text="My Panel"></div></div>

The default aggregation of the declarative support is usually also the default aggregation of the control as defined in the control's meta information. However, when no default aggregation is set or another aggregation should be used as a default, for example to avoid unnecessary meta tags, it can be useful to define a so-called default aggregration attribute on the parent controls HTML tag. This is done as follows:

data-sap-ui-default-aggregation="title"

With this, all children which are not included in the data-sap-ui-aggregation meta tag are added to the default aggregation. This is shown in the following example:

<div data-sap-ui-type="sap.ui.commons.Panel" data-sap-ui-default-aggregation="title"> <div data-sap-ui-type="sap.ui.commons.Title" text="My Panel"></div> <div data-sap-ui-default-aggregation="content"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 1"></div> <div data-sap-ui-type="sap.ui.commons.Button" data-text="My Button 2"></div> </div>/div>

You can now apply this to the MatrixLayout as follows:

<div data-sap-ui-type="sap.ui.commons.layout.MatrixLayout" data-layout-fixed="false> <div data-sap-ui-type="sap.ui.commons.layout.MatrixLayoutRow"> <div data-sap-ui-type="sap.ui.commons.layout.MatrixLayoutCell">

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 127

<div data-sap-ui-type="sap.ui.commons.TextField" data-value="Hello World"></div> </div> <div data-sap-ui-type="sap.ui.commons.layout.MatrixLayoutCell"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="Hello World"></div> </div> </div></div>

Or you can add ListItems to a ComboBox:

<div data-sap-ui-type="sap.ui.commons.ComboBox" data-value="Item 1"> <div data-sap-ui-type="sap.ui.core.ListItem" data-text="Item 1"></div> <div data-sap-ui-type="sap.ui.core.ListItem" data-text="Item 2"></div> <div data-sap-ui-type="sap.ui.core.ListItem" data-text="Item 3"></div> <div data-sap-ui-type="sap.ui.core.ListItem" data-text="Item 4"></div> <div data-sap-ui-type="sap.ui.core.ListItem" data-text="Item 5"></div></div>

1.1.3.7.7 Declarative Support: Data Binding

Data binding is supported seamlessly by the declarative support. Just add the model path in curly brackets and bind the model to the control (or parent control):

<div data-sap-ui-type="sap.ui.commons.Button" data-text="{/stringValue}" data-enabled="{model2>/booleanValue}"></div>

0..n aggregations can define templates to use for the aggregation binding:

<div data-sap-ui-type="sap.ui.commons.Carousel" data-content="{/buttons}"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="{title}"></div></div>

In the example above, the button template is used for the carousel content data binding.

Related Information

Data Binding [page 78]

1.1.3.7.8 Compiling Declarative HTML

The plugin only works for controls that are defined as declarative markup on startup time. To compile the declarative UI markup deferred, for example, when the markup is dynamically loaded and added to the DOM you can call the sap.ui.core.plugin.DeclarativeSupport.compile method, see the following code snippet:

<div id="button"> <div data-sap-ui-type="sap.ui.commons.Button" data-text="This button is added dynamically"></div></div>

128 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

<script> sap.ui.core.plugin.DeclarativeSupport.compile(document.getElementById("button"));</script>

1.1.3.8 SAPUI5 Components

Components are independent and resuable parts used in SAPUI5 applications. An application can use components from different locations from where the application is running. Thus, components can be developed by different development teams and be used in different projects.

NoteConstraints due to cross-origin issues also apply to components.

Components also support the encapsulation of closely related parts of an application into a particular component. This makes the structure of an application and its code easier to understand and to maintain.

SAPUI5 provides the following two types of components:

● UI components (class: sap.ui.core.UIComponent)UI components represent a screen area or element on the user interface, for example, a button or a shell, along with the respective settings and metadata.

● Faceless components (class: sap.ui.core.Component)Faceless components do not have a user interface and are used, for example, for a service that delivers data from a back end system.

The sap.ui.core.Component class is the base class for UI and faceless components. To extend the functionality, components can inherit from their base class or from another component.

Structure of a Component

A component is a folder. The folder name defines the component name and contains all optional and required resources that are used in the component except for the required SAPUI5 libraries and child components. Optional resources are, for example, the CSS and internationalization files, views, and images. The following files are mandatory for components:

● component.jsThis is the component controller and provides the runtime metadata (properties, aggregation, events) and the component methods. The name parameter that is passed to the component constructor represents the package name under which you can find the component.

● component.jsonThis is the component descriptor and contains the design-time metadata; you need this file for design-time environments such as the AppDesigner. The file is not loaded during runtime.

NoteAll paths within a component are relative paths to the component.js file and not to the index.html file.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 129

The following figure gives an example of a component folder structure.

The ComponentContainer control wraps a UI component. You use the control in the SAPUI5 control tree in the same way as any other control.

Related Information

Defining a Component for SAPUI5 from Scratch [page 130]Describes how to define a component for SAPUI5 from scratch

1.1.3.9 Defining a Component for SAPUI5 from Scratch

Describes how to define a component for SAPUI5 from scratch

This procedure describes how you create a new component for SAPUI5 from scratch. The example component used in the procedure has a button with configurable text.

1. Create a new folder with the name of your component, for example button.2. Create the following files in your folder:

○ Component.js

// define a new (simple) UIComponentjQuery.sap.require("sap.ui.core.UIComponent");jQuery.sap.require("sap.ui.commons.Button");jQuery.sap.declare("samples.components.button.Component");

// new Componentsap.ui.core.UIComponent.extend("samples.components.button.Component", {

metadata : { properties : { text: "string" }

130 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}});

samples.components.button.Component.prototype.createContent = function(){ this.oButton = new sap.ui.commons.Button("btn"); return this.oButton; };

/** Overrides setText method of the component to set this text in the button*/samples.components.button.Component.prototype.setText = function(sText) { this.oButton.setText(sText); this.setProperty("text", sText); return this;};

○ Component.json

{ "name": "samples.components.button", "version": "0.1.0", "description": "Sample button components", "keywords": [ "button", "example" ], "dependencies": { }}

The component is now ready to be used in an application. The following code snippet gives an example of the use of the component in two instances:

// Create a component var oComp1 = sap.ui.getCore().createComponent({ name: "samples.components.button", id: "Comp1", settings: {text: "Hello World"} }); // Create a Ui container var oCompCont1 = new sap.ui.core.ComponentContainer("CompCont1", { component: oComp1 }); // place this Ui Container with the Component inside into UI Area oCompCont1.placeAt("target1");

// You can also create a component and container at once. // In this example the container will create a new component according to the name. var oCompCont2 = new sap.ui.core.ComponentContainer("CompCont2", { name: "samples.components.button", settings: {text: "Hello World again"} }); oCompCont2.placeAt("target2");

Related Information

SAPUI5 Components [page 57]

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 131

Using UI Components in Applications [page 134]

1.1.3.9.1 component.js File

The component.js file is the component controller and provides the runtime metadata and the component methods.

A component can depend on the entire SAPUI5 library. If you only require particular controls, you can also start with the corresponding require statements directly. The following code snippet is an example for a declaration statement:

jQuery.sap.declare ("samples.Components.shell.Component");

To create a UI component, you extend the UI component's base class and pass to it the name of the new component and its package path as shown in the following code snippet:

// Shell Componentsap.ui.core.UIComponent.extent("samples.components.shell.Component", {[...]

The metadata provide the information to ensure the completeness of the elements of which the component consists of. This facilitates the decoupling of the application logic as much as possible from the logic within a particular component. The following metadata parameters can be defined in the component.js file:

● abstract● version● includes● dependencies

○ external○ libs○ components○ ui5version

● publicMethods● aggregations● library● autoDestroy● initOnBeforeRender

The following code snippet is taken from the component sample application and contains examples for all metadata parameters in the component.js file::

sap.ui.core.UIComponent.extend("samples.components.shell.Component", { metadata : { "abstract": true, version : "1.0", includes : [ "css/shell.css" ], //array of css and/or javascript files that should be used in the component dependencies : { // external dependencies libs : [ ],// array of required libraries, e.g. UX3 if your component depends on them

132 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

components : ["samples.components.products.overview", "samples.components.products.details", "samples.components.products.supplier"], // nested components - more about these, later on ui5version : "1.13.0" }, publicMethods: [ "render" ], aggregations: { "rootControl": { type: "sap.ui.core.Control", multiple: false, visibility: "hidden" } // needs to be set to enable databinding functionality }, library: "samples.components.shell", // inherited from ManagedObject, if omitted, the current package is automatically retrieved autoDestroy: false, // destroy component when view should be destroyed initOnBeforeRender: true }});

You can add a properties section to the metadata for all properties that can adopt different values during runtime. The getters and setters for these properties are generated automatically, but you can overwrite them if you require additional functionality.

sap.ui.core.UIComponent.extend("samples.components.shell.Component", { metadata : { "abstract": true, version : "1.0", includes : [ "css/shell.css" ],

[… omitting some lines to make the example shorter]

initOnBeforeRender: true, properties : { appTitle: { name:"appTitle", type:"string", defaultValue:"Default Value that will be replaced with something meaningful through the setter for this property" },someOtherProp: { name:"myProperty", type:"string", defaultValue:"Some text" } }, }});

You can use the following methods to control the initial instantiation of the component:

● initOverwrite this method for example to connect the model between the control and the component. This method is not called by the application directly, but called automatically when you create the instance of the component.

● createContentThe createContent method needs to be overwritten within your component implementation. You use this method to place all the code which is required to fill your component with the respective content, for example, creating an instance of the controls that should be used, or connecting the view that should be displayed. For the latter, you simply need to set this view to the view you whish to use. See the following code snippet for an example:

this.view = sap.ui.view({id:"myView",viewName:"samples.components.products.details.view.Details",type:sap.ui.core.mvc.ViewType.JS});

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 133

1.1.3.9.2 Using UI Components in Applications

To render UI components, you must wrap them in a ComponentContainer. UI components cannot be directly placed in a page with the placeAt method. A component container carries specific settings and also contains the lifecycle methods of a regular control, such as the onInit and onBeforeRendering methods. The methods of the ComponentContainer call the corresponding methods of the UI component internally.

Within an application, two different options to instantiate a ComponentContainer and a UI component exist. The following example assumes that the samples.components.button component exists and is loaded:

● Option 1: Create the component first, then add the component to the container, and finally use the placeAt method to place the component on the page:

var oComp = sap.ui.getCore().createComponent({ name: "samples.components.shell", id: "Comp1", settings: {appTitle: "Hello World 1"} });

var oCompCont = new sap.ui.core.ComponentContainer("CompCont1", { component: oComp }); oCompCont.placeAt("target1");

● Option 2: Pass the component to the componentContainer constructor:

var oCompCont2 = new sap.ui.core.ComponentContainer("CompCont2", { name: " samples.components.shell", settings: {text: "Hello World 2"} }); oCompCont2.placeAt("target2");

1.1.3.10 Component Configuration

You use the component configuration for the definition of static configuration for components. The configuration is available in the component metadata and you can access the configuration without creating instances of the component.

The following code snippet shows how you define the configuration for components.

sap.ui.core.UIComponent.extend("sap.samples.Component", {

metadata : { version : "1.0", config: { "sap.samples.config1": { "Key1-1": "Value1-1", "Key1-2": "value1-2" }, "sap.samples.config2": {

134 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

"Key3-1": "Value3-1", "Key3-2": "Value3-2" } } }});

To access the configuration without creating an instance of the component, simply require the component as follows:

jQuery.sap.require("sap.samples.Component");var oConfig = sap.samples.Component.getMetadata().getConfig();

A component instance can access its configuration as shown in the following code snippet:

[...]

init: function() { var oConfig = this.getMetadata().getConfig(); }

[...]

When you extend a component and add additional configuration, the configuration is merged with the original component:

sap.samples.Component.extend("customer.Component", {

metadata : { version : "1.0", config: { "sap.samples.config1": {

"Key1-3": "Value1-3"

}, "customer.config1": { "Key1-1": "Value1-1" } } }});

The merged configuration then looks as follows:

var oConfig = { "sap.samples.config1": { "Key1-1": "Value1-1", "Key1-2": "value1-2", "Key1-3": "Value1-3" }, "sap.samples.config2": { "Key3-1": "Value3-1", "Key3-2": "Value3-2" }, "customer.config1": { "Key1-1": "Value1-1"

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 135

}};

1.1.3.11 Extensibility Concept: Adapting SAPUI5 Applications

SAPUI5 supports the adaptation of standard applications to specific requirements. The information about the adapted objects is stored in the component configuration. The standard application itself is not changed. The customized application becomes the start-up project and launches the standard application with the additional customizing configuration.

SAPUI5 supports the following adaptations of the standard::

● View extensions by using extension points to insert custom content (views or fragments)● Replacing standard views with customized views● Modifying views by changing specific properties● Controller extensions by adding code or overriding existing code● Customizing i18N resource texts

1.1.3.11.1 Example: Component Configuration

The component configuration contains the required information about the extension metadata and the objects that are replaced or extended. It is contained in the component.js file of the custom application.

Note● The component of the custom application needs to inherit from the main component of the original

application.● To make the location of the original application or component known to SAPUI5, it may be necessary to use

registerModulePath(...).● The configuration in the customizing section contains the extension metadata and describes the objects

that are replaced or extended.

To The following code snippet shows an example of a configuration structure.

some.sap.Component.extend("some.customer.Component", { metadata : { .....some configuration config: { .....some configuration }, customizing: { "sap.ui.viewExtensions": { "samples.components.ext.sap.Sub2": { "extension2": { className: "sap.ui.core.Fragment", fragmentName: "samples.components.ext.customer.CustomFrag1", type: "XML"

136 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}, "extension3": { className: "sap.ui.core.mvc.View", viewName: "samples.components.ext.customer.CustomSubSubView1", type: "XML" } } }, "sap.ui.viewModifications": { "samples.components.ext.sap.Sub3": { "customizableText": { "visible": false } } },

"sap.ui.viewReplacements": { "samples.components.ext.sap.Sub1": { viewName: "samples.components.ext.customer.CustomSub1", type: "XML" } }, "sap.ui.controllerExtensions": { "samples.components.ext.sap.Main": { "controllerName": "samples.components.ext.customer.MainExtension" } } } }});

"sap.ui.viewExtensions": Provides customized view content in a specified extension point in the standard application

sap.ui.viewModifications": Used for overriding control properties of the standard application

"sap.ui.viewReplacements": Used for replacing a standard view with a customized view

"sap.ui.controllerExtensions": Used for replacing a standard controller with a customized controller

1.1.3.11.2 View Extension

SAPUI5 uses extension points to indicate the position within a view where you can insert customized content. You insert the extension point in a standard view. In the code snippet below, three extension points are defined: extension1, extension2. and extension.

<mvc:View xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"> <core:ExtensionPoint name="extension1" /> <TextView text="SAP View 'Sub2' - this one is extended by the customer and there should be a button after this text"></TextView> <core:ExtensionPoint name="extension2" /> <core:ExtensionPoint name="extension3" /> </mvc:View>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 137

In the component customizing you can then assign the customized view to the respective extension point:

customizing: { "sap.ui.viewExtensions": { "samples.components.ext.sap.Sub2": { "extension2": { className: "sap.ui.core.Fragment", fragmentName: "samples.components.ext.customer.CustomFrag1", type: "XML" }, "extension3": { className: "sap.ui.core.mvc.View", viewName: "samples.components.ext.customer.CustomSubSubView1", type: "XML" } }, .....some more content

The following code snippet gives an example of a customized view that is assigned to extension2:

<mvc:View xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"> <core:ExtensionPoint name="extension1" /> <TextView text="Customer View 'SubSubView1' - this one extends the original SAP View 'Sub2' - and even custom Views can be extended:"></TextView> <core:ExtensionPoint name="extension2" /> </mvc:View>

1.1.3.11.3 View Modification

You can modify views by changing the property of a standard view control. The following code snippets give an example for a view modification. The someCustomizableTextControl control of the standard view Sub3.view.xml shall not be visible in the modified view:

<mvc:View xmlns="sap.ui.commons" xmlns:mvc="sap.ui.core.mvc"> <TextView text="SAP View 'Sub3' - the text after this one is hidden by customizing: "></TextView> <TextView id="someCustomizableTextControl" text="This text is made invisible by customization"></TextView> </mvc:View>

In customizing, you identify the customizableText controller and set the visible property to false:

customizing: { "sap.ui.viewModifications": { "samples.components.ext.sap.Sub3": { "someCustomizableTextControl": { "visible": false } } }}

138 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.11.4 View Replacement

If the extension of a view is not sufficient to meet your requirement, you can replace a standard view with a customized view. The following code snippet gives an example for a view replacement.

The following view is delivered in the standard application:

<mvc:View xmlns="sap.ui.commons" xmlns:mvc="sap.ui.core.mvc"> <TextView text="SAP View 'Sub1' - this one should have been replaced by the customer View"></TextView> </mvc:View>

You want to replace this standard view with the following customized view:

<mvc:View xmlns="sap.ui.commons" xmlns:mvc="sap.ui.core.mvc"> <TextView text="Custom View 'Sub1' - this one replaces the original SAP View 'Sub1'"></TextView> </mvc:View>

You connect the two views in customizing:

customizing: { .....some more content "sap.ui.viewReplacements": { "samples.components.ext.sap.Sub1": { viewName: "samples.components.ext.customer.CustomSub1", type: "XML" } }, .....some more content

1.1.3.11.5 Controller Extension

In SAPUI5, you can extend or overwrite the functionality of a base controller by merging the standard controller with a new controller that meets your specific requirements.

NoteThe controller extension concept of SAPUI5 does not use inheritance but merging on JavaScript object level.

The methods of your new controller override the standard methods with the same name. The following controller lifecycle methods are, however, an exception to this rule: onInit, onExit, onBeforeRendering, onAfterRendering. The controller methods of your customized application are called either after (for onInit and onAfterRendering), or before (for onExit and onBeforeRendering) the standard lifecycle methods. The following code snippets show how the replacment of controllers works.

The following code snippet shows the standard controller Main.controller.js that you want to replace:

sap.ui.controller("samples.components.ext.sap.Main", { onInit : function () { console.log("samples.components.ext.sap.Main - onInit"); },

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 139

doSomething: function() { alert("this is an original standard action"); },

doSomeStandardAction: function() { alert("this is another original standard action"); }});

You replace the standard controller with the following new controller CustomMain.controller.js:

sap.ui.controller("samples.components.ext.customer.CustomMain", { onInit : function () { console.log("samples.components.ext.customer.CustomMain - onInit"); },

doSomething: function() { alert("this is a customer action"); },

doSomeCustomAction: function() { alert("this is another customer action"); }});

Im customizing, you connect the new controller with the standard controller:

customizing: { "sap.ui.controllerExtensions": { "samples.components.ext.sap.Main": { controllerName: "samples.components.ext.customer.CustomMain" } }, .....some more content

With this customizing, the samples.components.ext.customer.CustomMain controller functions are merged every time the controller is called. The log contains the following messages after initialization:

samples.components.ext.sap.Main - onInitsamples.components.ext.customer.CustomMain - onInit

The doSomething method of the new controller overwrites the doSomething method of the standard Controller. Thus, if the method is invoked, an alert popup with the following text appears: this is a customer action.

The doSomeStandardAction method remains available without changes, as no method with the same name exists in the new controller.

The doSomeCustomAction method is additionally available and you can use it, for example, in a view extension.

The controller extensions are applied to all controllers with the specified name within the customized component, regardless of whether the controller is instantiated explicitly or belongs to a view.

Providing Hooks in the Standard Controller

Controller extensions can override any method. As this is a powerful but also fragile feature, you can provide specific extension points in the controller code, so-called hooks. You can document these controller points and keep them stable, thus providing more robust hooks across application updates for your extensions.

140 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The process for this is as follows:

1. In the application, identify a strategic location within the controller code where customers may want to plug in and execute their customized code.

2. In the application, define a new function name which is reserved for the extension, document the function and any arguments the function may receive or return.

3. Add code lines in the application (see code snippet below) to check whether the function has been implemented, and, if so, to call the function. We also recommend to implement sanity checks for return values.

4. The customer can then configure a controller extension, implementing exactly this one function.5. The SAPUI5 runtime merges the new controller extension into the standard controller. If the customizing is

enabled, the new function can be executed.

Example

By receiving the data object oSomeData from the server, the application enables you to access and modify the data object. The extension function name is onDataReceived and gets a reference to the data object as argument.

Standard controller:

// ...data object oSomeData has been received, possibly from an Ajax response... if (this.onDataReceived) { // check whether any extension has implemented the hook... this.onDataReceived(oSomeData); // ...and call it } // ...continue working with the (now possibly modified) data...

New controller:

sap.ui.controller("customer.xy.Sub2ControllerExtension", { onDataReceived: function(oData){ // oSomeData will be passed in if (oData && oData.status === "important") { oData.message = oData.message + "!!!"; // modify some part of the data object, adding exclamation marks to a message text } } // no need to return anything as in this example the original object is modified});

NoteThis only works for one extension layer as the most specific or last extension overrides any other hook implementations. To allow multi-layer extensions, we recommend that middle-layer extensions provide and document their own hook functions.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 141

1.1.3.11.6 Controller Replacement

For a view replacement, you can either use the standard controller of the replaced view by setting its name as controllerName, or use and extend the standard controller, or you can replace the controller by specifying a new controller name in the new view and implementing the new controller.

1.1.3.11.7 I18n Resource Text Customization

You can enhance the sap.ui.model.resource.ResourceModel with customized resource bundles. For this, the ResourceBundle provides the possibility to enhance it with other bundles:

var oModel = new sap.ui.model.resource.ResourceModel({bundleUrl:"./testdata/messages.properties"});oModel.enhance({bundleUrl:"./testdata/messages_custom.properties"});

An enhanced ResourceModel tries to resolve the i18n texts from the customized bundle first. If a text does not exist there, it tries to look up the i18n text in the standard bundle.

The additional resource bundles are not part of the customizing configuration, but can be added as part of a controller extension.

1.1.3.11.8 Supportability and Limitations

If a customized application does not run properly, you can disable the customizing. In a support case, for example, you can set a breakpoint early in the sap-ui-core.js and then execute the following code in the console:

#!js window["sap-ui-config"] = window["sap-ui-config"] ||{}; window["sap-ui-config"]["xx-disableCustomizing"] = true;

NoteFor security reasons, it is not possible to use a URL parameter.

View Modifiation (with <core:ExtensionPoint />) and Control property modification are supported only for XML type of views Control property modification is only possible for the "visible" property and only for controls which have a given ID (one which is specified in the XMLView)

Limitations

The view modifications by means of extension points and the modification of control properties are only supported for XML view types.

142 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The control property modification is only supported for the visible property and only for controls with a given ID specified in the XML view.

1.1.3.12 Navigation

Navigation in SAPUI5 enables you to pass data from the hash to any view, and to adjust a current hash so that you can use it as a bookmarkable URL. Depending on the hash, you can also generate views automatically.

To notify your application that a hash has changed to a certain value, you use a route. If the route matches the hash, it provides the data that has been passed over to the hash to a defined handler. If you use a UI component, the component creates the router, see [Link]. In the following example, the URL is www.myApp.com#product/5. To get the information that the hash points to the product and that the value is "5", you need the following configuration:

//Somewhere at the start of your application var aRoutes = [ { pattern : "product/{id}", // will be the url and from has to be provided in the data name : "specificProduct" // name used for listening or navigating to this route } ];

var oRouter = new sap.ui.core.routing.Router(aRoutes);

//this is used to retrieve the instance again oRouter.register("appRouter");

//starts reacting on the hashchange + parses the current hash and notifies callbacks oRouter.initialize();

With this configuration, the route pattern is matched against the hash. The curly brackets indicate that this segment of the URL is passed to a handler with the contained value. In the example the value is "5".

The following code snippet shows how you can register to this:

sap.ui.controller("MyApp.View1", { //inside of a controller onInit: function() { var oRouter = sap.ui.core.routing.Router.getRouter("appRouter");

oRouter.attachRouteMatched(function(oEvent) { if (oEvent.getParameter("name") !== "specificProduct") { return; //we only want to react to events for the specificProductRoute } //We now know we hit the specificProduct route and retrieve the id this._selectItemWithId(oEvent.getParameter("arguments").id); //bind the this pointer to the callback }, this); },

_selectItemWithId : function(id) { //implementation eg: select an item in a list }

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 143

1.1.3.12.1 Routing in UI Components

UI Components can intitialize a router based on the component metadata. For the routing metadata, the following two parameters exist:

● routes: Contains an array with all routes defined by the component● config: Contains default values; the default values are applied, if the route does not specify a setting and are

overwritten by custom values

metadata : { ... routing: { config: { // default values for routing viewType : "XML", viewPath: "default.path.view", clearTarget: false }, routes: { // contains routing configuration objects "myRouteName" : { name : , pattern : "FirstView/{from}", view : "myViewId" } } } ...}

To intialize the router, the UI component uses the init function as follows:

init : function() { sap.ui.core.UIComponent.prototype.init.apply(this, arguments); // this component should automatically initialize the router! this.getRouter().initialize();}

To access the router and to use its functions, use the getRouter() function or the static getRouterFor function of the UI component. You can pass either a controller, or a view:

var oRouter = sap.ui.core.UIComponent.getRouterFor(this);

All views which are generated by the router are automatically created in the context of the respective UI component.

1.1.3.12.2 Configuration Parameters for Navigation

To use navigation in SAPUI5, you have to provide configuration for routes and for the router. The following configuration parameters exist for routes:

● name (mandatory)The route name parameter identifies the route and has to be unique within one router instance. If you add a callback on the routeMatched event of the router, you need to check for the route name. You also need to provide the route name as first parameter if you want to use the navTo method of the router.

144 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Example:

"routing" : { // name used for listening or navigating to this route "specificProduct" : { //all the optionalParameters } }

● pattern (optional)The pattern parameter defines the string that is matched against the hash. Only the first route with a matching pattern triggers the callback. The following special character and URL segments exist:

○ / - seperator for a URL segment○ {variableName} - mandatory variable, for example foo/{bar} does not match against the hash /foo○ :optionalVariableName: - optional variable, for example foo/:bar: matches against foo/, but bar

is undefined in the callback○ :myVariable*: - ignores separators and puts everything that follows in this variable, for example foo/

{bar*} matches against foo/bar/one and the value of bar is "bar/one"○ :query?: - puts the key value pairs into a query variable, for example ?foo=bar&one=two adds a

parameter { query : { foo : "bar" , one : "two" } }

NoteUndefined patterns match the empty hash. You usually only skip the pattern for subroutes and subroutes are registered before their parents. So, as a workaround, use the same pattern as one of the subroutes.

● subroutes (optional)The subroutes parameter contains an array of routes and can contain the complete route configuration. Routes that are added to subroutes may have subroutes themselves.

● view (optional)The view parameter contains the name of the view that is created on the first time a route is matched. To place the view in a control, use targetAggregation and targetControl. Views are only created once.

● viewType (optional)The view type parameter defines the view type that is created.

● viewPath (optional)The view path parameter specifies a prefix that prepends the view; if, for example, view is set to "myView" and viewPath is set to "myApp", the created view is myApp.myView.

● targetParent (optional)The target parent parameter defines the ID of the parent of the targetControl parameter.

● targetControl (optional)Views are put into a container control, for example a shell control or a NavContainer for mobile applications, or into any other container. The targetControl parameter contains the ID of this control.

● targetAggregation (optional)The target application parameter contains the name of an aggregation of the target control that contains views. A NavContainer, for example, has an aggregation called Pages and the shell container has Content.

● clearTarget (optional)The clear target parameter defines a boolean that is used to specify if the aggregation should be cleared before adding the view to it.

● callback (optional)The callback parameter is an optional function that is executed after the route has matched.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 145

The router configuration supports the same values as the route. If the route does not provide a value, the application uses the router configuration. The following code snippet gives an example:

//provides the default values for all viewsvar oRouterConfig = { viewType : "XML", viewPath: "MyApp.view", };var aRoutes = [{ viewType : "JS", pattern : "foo", name : "myRoute"}];

//results in following config:

{ viewPath: "MyApp.view", viewType : "JS", pattern : "foo", name : "myRoute"}

1.1.3.12.3 Methods and Events for Navigation

You use the navTo(routeName, data) method to navigate to the given route and to fill the hash with data. Data is also provided to the listener callbacks of controllers that listen to this route.

sap.ui.controller("MyApp.View2", {

anyEvent: function() { sap.ui.core.routing.Router.getRouter("appRouter").navTo("View2",{ from: "View 1"}); }});

NoteThe hash in this example will not change to product/5 because view1 matches the name of the route defined in the example configuration.

The productId property of the data object has to match the placeholder in the pattern of the route. The listeners to the hash are informed because the hash is changed.

SAPUI5 provides the following events for navigation: routematched and viewcreated.

The route matched event is fired every time a changed hash matches a route. If you only want to react to specific routes, check if the name parameter matches the route you want to listen to. The event has the following parameters:

● name - name of the route that has matched● arguments - object of arguments that are part of the route● targetControl - control instance, in which the view was inserted (only if targetControl is provided)

146 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● view - instance of the view

Example:

sap.ui.controller("MyApp.View1", {

onInit: function() { var oRouter = sap.ui.core.routing.Router.getRouter("appRouter");

oRouter.attachRouteMatched(function(oEvent) { if (oEvent.getParameter("name") === "view1") {

this._selectItemWithId(oEvent.getParameter("arguments").id);

}, this); },

_selectItemWithId : function(id) { //implementation }

The viewcreated event is fired every time a new view has been created by the navigation system. The event has the following parameters:

● view - view instance● viewName - name of the view● type - view type

1.1.3.12.4 Route Matching

For route matching, the order of route definition is important: Only the first matching route will be matched. Therefore, define specific routes first as shown in the following code snippet:

//this is '''correct'''{ "firstRoute" : { "pattern" : "foo/bar" }, "secondRoute" : { "pattern" : "foo/{id}" }}

In this example, #foo/bar matches the first route and foo/anything matches the second route.

If you do it the other way round as shown in the following example, the secondRoute is hit passing bar as ID whereas the first route will never be hit:

//this is '''correct'''{ "firstRoute" : { "pattern" : "foo/bar" }, "secondRoute" : { "pattern" : "foo/{id}" }}

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 147

1.1.3.12.5 Building a Catchall Route

For requests that do not match any route, you can use catchall routes. If you define a catchall route, make sure that you define it as the last route, because the first route that gets hit is informed. All routes after this route are ignored.

Example:

routes : [// a lot of other routes before this one{ pattern : ":all*:", //catchall viewId : "Master", // any request not matching a hash will go to master name : "catchall", // name used for listening or navigating to this route } ]

1.1.3.13 HTML Templating in SAPUI5

The HTML templating concept in SAPUI5 is based on handlebars, which supports you in building semantic templates. You can either use standard expressions and helpers together for the context of a template instance, or the custom helpers for handlebars provided by SAPUI5, which you can use together with the SAPUI5 models. This enables you to bind texts against properties in the model. If the property in the model changes, the text is updated accordingly. You can create and bind the value DOM elements including their DOM attributes. For input DOM elements like INPUT, TEXTAREA or SELECT, SAPUI5 establishes a two-way binding: On change of the DOM element value the model is updated if the value is bound against a SAPUI5 model. You can also define controls in the template similar to the declarative support but in handlebars helper notation.

Prerequisites

To get started with HTML templating, you must comply with the following requirements:

● An inline template is defined.● The templating framework is triggered to parse the inline template.

Example:

// register all available templates in the documentsap.ui.template();

<div id="myControlTemplate" data-type="text/x-handlebars-template"> <h3>Control Template (using "control" expression)</h3> {{control sap-ui-type="sap.ui.commons.Label" design="Bold" text="{/title}"}} <ul> {{#each path="/persons"}} <li>{{control sap-ui-type="sap.ui.commons.TextView" text="{lastName}, {firstName}"}}</li> {{/each}} </ul>

148 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

</div>

1.1.3.14 Expressions and Helpers for HTML Templating

For HTML templating in SAPUI5, you can use the following expressions and helpers:

● plain handlebarsThe plain handlebars expressions do not refer to SAPUI5 models, but to a context which is passed along when, for example, an instance for the template is created. The following example shows how you can use plain handlebars expressions and helpers.

<h3>{{title}}</h3><ul>{{#each persons}} <li>{{firstName}} {{lastName}}</li>{{/each}}</ul>

For more information about handlebars expressions and helpers, see the handlebars documentation.● SAPUI5-specific helpers

SAPUI5 provides the following helpers for HTML templating

○ {{text}}You use the text helper to bind texts to properties of SAPUI5 models. The helper registers to changes in the SAPUI5 model and updates the template instance if the property in the model changes. When the templating engine parses the helper, it is replaced with the new value in the model. The path attribute supports the standard SAPUI5 data binding syntax.Example: {{text path="/title"}}To bin proprties from named models, such as translatable text, you can specify this in the path attribute as follows:{{text path="i18n>MY_TEXT"}}

○ {{element}}You use the element helper to create single DOM elements. You can nest DOM elements and bind DOM attributes against values of the model.Example: {{element tag="div" text="Hello World" data-myattr="myvalue" style="border: 1px solid black;" class="myStyleClass"}}Example for use with data binding with a span DOM element as default tag name: {{element text="{/title}"}}Example for use with data binding and named models: {{element tag="div" text="{i18n>MY_TEXT}"}}Example for use with editable DOM elements for two-way binding (binding the value of an input field against a model property):

{{element tag="input" value="{/title}"}}{{element tag="textarea" text="{/title}"}}

DOM elements have the advantage that you can update them individually when the property value in the model has changed. You do not need to re-render the template completely.

○ {{control}}

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 149

You use the control helper to creat or embed SAPui5 controle intro a template instance. It is aligned with declarative support. The following example shows how you embed a sap.ui.commons.TextField in a template:{{control sap-ui-type="sap.ui.commons.TextField" value="{/title}"}}

○ {{each}}You can use the each helper together with SAPUI5 data binding by specifiying the path attribute:

{{#each path="/persons"}} {{element text="firstName"}}{{/each}}

1.1.3.15 Example: Use of HTML Templating in SAPUI5

The following example demonstrates the use of the helpers for HTML templating that can be used in SAPUI5:

<!DOCTYPE HTML><html><head>

<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Template - sap.ui.core.tmpl</title>

<script id="sap-ui-bootstrap" type="text/javascript" src="resources/sap-ui-core.js" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection" data-sap-ui-xx-bindingSyntax="complex" > </script> <script> // sample code jQuery(function() { // define the model var oModel = new sap.ui.model.json.JSONModel({ title: "Persons", persons: [{ firstName: "Peter", lastName: "Muessig" }, { firstName: "Tim", lastName: "Back" }, { firstName: "Christoph", lastName: "Kraemer" }] }); sap.ui.getCore().setModel(oModel); // register all available templates in the document sap.ui.template(); });

150 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

</script>

</head><body class="sapUiBody" role="application">

<div id="mySimpleTemplate" data-type="text/x-handlebars-template"> <h3>Text Template (using "text" expression)</h3> <b>{{text path="/title"}}:</b> <ul> {{#each path="/persons"}} <li>{{text path="firstName"}} {{text path="lastName"}}</li> {{/each}} </ul> </div>

<div id="myAdvancedTemplate" data-type="text/x-handlebars-template"> <h3>Advanced Text Template (using "element" expression)</h3> {{element tag="b" text="{/title}"}}: <ul> {{#each path="/persons"}} {{element tag="li" text="{firstName} {lastName}"}} {{/each}} </ul> </div>

<div id="myAdvancedEditTemplate" data-type="text/x-handlebars-template"> <h3>Advanced Text Template (using editable "element" expression)</h3> {{element tag="textarea" text="{/title}" rows="2" cols="40"}} <ul> {{#each path="/persons"}} <li>{{element tag="input" value="{firstName}"}} {{element tag="input" value="{lastName}"}}</li> {{/each}} </ul> </div>

<div id="myControlTemplate" data-type="text/x-handlebars-template"> <h3>Control Template (using "control" expression)</h3> {{control sap-ui-type="sap.ui.commons.Label" design="Bold" text="{/title}"}} <ul> {{#each path="/persons"}} <li>{{control sap-ui-type="sap.ui.commons.TextView" text="{lastName}, {firstName}"}}</li> {{/each}} </ul> </div>

<div id="myControlEditTemplate" data-type="text/x-handlebars-template"> <h3>Advanced Control Template (using editable "control" expression)</h3> {{control sap-ui-type="sap.ui.commons.TextArea" value="{/title}" rows="2" cols="40"}} <ul> {{#each path="/persons"}} <li>{{control sap-ui-type="sap.ui.commons.TextField" value="{lastName}"}}, {{control sap-ui-type="sap.ui.commons.TextField" value="{firstName}"}}</li> {{/each}} </ul>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 151

</div>

</body></html>

1.1.3.16 Modularization and Resource Handling

The following sections provide information abour the modularization concepts and resource handling for SAPUI5.

1.1.3.16.1 Modularization and Dependency Management

The SAPUI5 framework has built-in support for modularizing comprehensive JavaScript applications. That means, instead of defining and loading one large bundle of JavaScript code, an application can be splitted into smaller parts which then can be loaded at runtime at the time when they are needed. These smaller individual files are called modules.

To load a module, the jQuery.sap.require function must be used. Assume the following page:

#!js

<!-- UI5 bootstrap tag --> <script id="sap-ui-bootstrap" src="./resources/sap-ui-core.js" data-sap-ui-libraries="sap.ui.commons"></script>

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

function onPressButton() { sap.ui.commons.MessageBox.alert("Hello World!"); }

</script>

At first, the SAPUI5 framework initializes and then loads the sap.ui.commons.MessageBox module. Internally, the framework analyzes the module name and derives the module URL from it:

./resources/sap/ui/commons/MessageBox.js

The module script is then loaded from that URL and executed.

What is a Module

A module simply is a JavaScript file that can be loaded and executed in a browser. There are no rules or definitions what code belongs to a module, and what code does not. It is up to the developer what content to bundle into a single module. But typically, the content of a module has some topic in common. Either it forms a JavaScript class or namespace, or the contained functions address a specific topic, for example client to server communication, mathematical functions, and so on.

152 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

There is also no special syntax or structure defined for modules. However, there are some features that module developers should be aware of and that they can use:

Name: A module is loaded by calling jQuery.sap.require with the name of the module. So, all modules are identified by a name. Human readers often associate a module with the main JavaScript object declared in it. Therefore, the module names by convention are a hierarchical sequence of dot-separated identifiers (like sap.ui.core.Core). It is best practice to use all but the last identifier to group modules in a logical and/or organizational way (much like packages in Java) and to use the last identifier to give the module a meaningful, semantical name, for example, the 'topic' common to the code in the module.

Declaration: Modules can declare themselves by calling the static jQuery.sap.declare function with their name. This helps SAPUI5 to check at runtime whether a loaded module really contains the expected content (compare the required name against the declared name). As a side effect, jQuery.sap.declare will ensure that the parent namespace of the module name exists in the current global namespace (window). More details can be found in the API documentation of declare.

If a module does not contain a declaration, the framework assumes that the module has the expected content and automatically declares it with the name used for loading it. In some rare cases - which are explained below - a module declaration is mandatory.

Description: Furthermore, modules can contain a description which helps others to decide whether a module is useful for them, or not. By convention, any JavaScript comment preceeding a module's declaration (jQuery.sap.declare statement) is interpreted as its description. The configuration UI displays such descriptions next to the module name.

Dependencies: Last but not least, modules can use the jQuery.sap.require method to load other modules that they depend on. While jQuery.sap.require internally has the effect of a "loadModule" call, it can also be regarded as a dependency declaration (therefore its name 'require'). These dependency declarations can be evaluated at runtime (as explained above), but they can also be analyzed at built time or at runtime on the server.

Example:

A typical module that uses all of the above features might look like this (the module name is my.useful.SampleModule);

#!js

/* * A short documentation of the module. This documentation is not evaluated at runtime, only during build time */ jQuery.sap.declare("my.useful.SampleModule"); // declaration of the module. Will ensure that the containing namespace 'my.useful' exists.

// 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 = {};

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 153

Loading a Module

As mentioned already, modules are loaded by calling function jQuery.sap.require with the name of a required module. The framework then checks whether the named module is loaded already. If so, the function simply returns. Otherwise it tries to load and execute the module synchronously. If any of these two steps fails, an exception is thrown and execution of the calling module thereby is disrupted.

To summarize it: A call to jQuery.sap.require ensures that the required module is loaded and has been executed before execution of the caller continues (*). (*) this is only true as long as no cyclic dependencies occur.

When loading a module, its dot-separated name must be transformed to an URL. This is done by replacing all dots ('.') with slashes ('/') and appending the standard suffix '.js' to it. This transformed name is then appended to the UI5 resource root URL (a prefix of the URL where UI5 has been loaded from, see explanation of bootstrap). The resulting URL is then used to load the module as a text. If loading succeeds, the module is first declared with the original module name and then executed in a global context (window). If either loading the module or executing it fails, the module name is internally marked as "failed" and an exception is thrown indicating the cause for the failure. Any further tries to load the same module will fail immediately, reproducing the same error message.

Multiple Module Locations

It is a common use case for web applications that different modules are located in different locations (servers, web apps). Imagine for example that your web application is deployed as an individual web app and that it contains some very important modules to be loaded at runtime. But for administrative reasons, SAPUI5 and its provided modules have to be loaded from a content delivery network (CDN) or from a centrally deployed web app. As explained above, SAPUI5 by default will try to load any required modules from its resource root URL, namely from the centrally deployed web application. This would fail for the modules contained in your web application.

Such mixed location scenarios are supported with the jQuery.sap.registerModulePath function:

jQuery.sap.registerModulePath = function(sModuleNamePrefix, sURL);

It associates a module name prefix with an URL prefix. Any module whose name starts with the module name prefix will be loaded from the registered URL instead of the standard resource root URL. In the scenario prethought above, this can be used to redirect the request for the application-specific modules to the corresponding web application:

#!js

<!-- bootstrap tag which implicitly defines the resource root as 'http://www.sap.com/sapui5/1.0/resources/' --> <script src="http://www.sap.com/sapui5/1.0/resources/sap-ui-core.js" ></script>

<script> // request will be mapped to http://www.sap.com/sapui5/1.0/resources/sap/ui/core/Core.js jQuery.sap.require('sap.ui.core.Core');

// redirect the 'my.webapp' package to the local web app jQuery.sap.registerModulePath('my.webapp', '/my-webapp/resources/my/webapp/');

// loads /my-webapp/resources/my/webapp/MyModule01.js jQuery.sap.require('my.webapp.MyModule01'); </script>

154 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteThe registered URL above contains the transformed module name prefix 'my/webapp/'. While this seems to be an unnecessary redundancy in the registration, it allows a more flexible packaging of the modules. For example, a company might decide to deploy all its specific modules named 'my.company.*' to the central URL 'http://my.company/shared/' without packaging them into a two level hierarchy of subfolders:

jQuery.sap.registerModulePath('my.company', 'http://my.company/shared/');

However, when the standard build tools of the SAPUI5 framework are used, the full package name will be part of the runtime file hierarchy and the registration must contain the transformed package hierarchy as above.

Dependency Resolution Tools

The previous section contained some explanations how dependencies between modules are resolved on the client at runtime. During development, this is the typical use case. Modules can be modified in the development environment and can be deployed as individual entities to some runtime. When the client then is refreshed - and if caching is configured properly - it will reload only the modified modules.

In productive systems however, it might be desirable to bundle again several modules into one single file. This helps reducing the number of necessary roundtrips and can thereby help to reduce the impact of network latency. However, one doesn't want to loose the flexibility and transparency of the dependency management.

The SAPUI5 framework supports this with a dependency resolution tool. It analyzes a module file and all its dependencies and creates a new file containing the original module content, as well as any required modules. It automatically avoids double inclusion of modules. The tool can be used in two ways: Either via an Ant task at build time to create a merged super module which then can be referenced in any HTML page instead of the original file; or at runtime, then using a servlet on server side.

How to Avoid Duplicates

When the runtime dependency resolution is used, the runtime maintains a list of the loaded modules. Before a new module is loaded and executed, the list is searched for it and if found, the module is not loaded again. But when the server or build-time tool is used, it creates a bigger file potentially containing multiple modules. The runtime then can only check in advance whether that bigger module has been loaded already. It does not know about the contained modules and therefore can not avoid double-loading of them. To compensate this, the dependency resolution tool wraps any embedded module with a few lines of additional coding. These additional checks will be evaluated during execution of the merged module and will have the same effect as the original runtime checks in an unmerged scenario:

...

// code of enclosing module ...

// location of a jQuery.sap.require('xyz');

if ( !jQuery.sap.isDeclared('xyz') ) { // check whether module 'xyz' has been

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 155

loaded already

jQuery.sap.declare('xyz'); // will only be added if the module 'xyz' doesn't contain a declaration

// original text of module 'xyz' ... }

... // further code of enclosing module ...

NoteThe generated wrapper coding will also contain a module declaration if the module doesn't contain one. The wrapper avoids double loading no matter whether a module has been loaded as an individual file or as part of a bigger, merged module. It is even possible to recursively merge files (merged module A includes a merged module B).

Why not Simply Concatenating Modules?

One might wonder why multiple modules can not simply be concatenated into a bigger module. Why have the modules to be parsed and to be nested according to the original jQuery.sap.require calls? The answer simply is that this makes the runtime behavior of the merged file more predictable. As soon as you look at concrete modules with complex (or even cyclic) dependencies, order of module execution becomes significant. The main promise of jQuery.sap.require that the caller continues only after the required module has been successfully loaded and executed can be hold only if the required module is embedded exactly at the place where the jQuery.sap.require call was located.

In cases where a use of the dependency resolution tool is not possible at all, one might indeed simply concatenate modules. But then the following two criteria must be ensured 'manually' by the developer:

● The order of the files must obey the dependencies. A module must not 'require' another module that is only merged later on.

● All merged modules must do a declaration with jQuery.sap.declare, otherwise the framework will not know that the modules have been loaded and potentially load them again.

Configurator Servlet

As mentioned already, one way of executing the dependency resolution tool is to call it via a servlet. Such a servlet has been included in the phoenix-cdn application that is part of our drop. By default, the servlet is configured to react on the URL http:// host:port /sapui5/download/configurator. It accepts several parameters

156 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

URL Parameter Default Description

modules None Mandatory: A comma separated, ordered list of module names that should be included in the resulting module. If the parameter occurs multiple times, the values will be concatened

out "sap-ui-custom.js" Name of the resulting module. The resulting module will contain a declaration with that name. When the servlet is used from the configurator Web UI, then the name will also be suggested in the download dialog.

minimize False Activates the JavaScript minimization for the output (experimental feature)

The Configurator WebUI, which is part of phoenix-cdn as well, uses the servlet to create a downloadable JavaScript file containg all selected modules.

But it is also possible to use the servlet directly from within an application page and to load UI5 and the required controls etc. in one step. The following HTML fragment shows an example (line breaks added for better readability):

<script id="sap-ui-bootstrap" data-sap-ui-theme="sap_platinum" type="text/javascript" data-sap-ui-libs="sap.ui.commons" src="/sapui5/download/configurator?modules=jquery-1.4.2,jquery.sap.global,sap.ui.core.Core,sap.ui.commons.Button,sap.ui.commons.ButtonRenderer,sap.ui.commons.layout.MatrixLayout,sap.ui.commons.layout.MatrixLayoutRow,sap.ui.commons.layout.MatrixLayoutCell,sap.ui.commons.layout.MatrixLayoutRenderer" > </script>

Special Cases

How to Load jquery.sap.require?

Obviously, modules can only be loaded as soon as the jQuery.sap.require function is available. The implementation of this function is located in module 'jquery.sap.global' which in turn requires jQuery itself (located in module 'jquery-1.7.1'). At runtime, these two modules can not be loaded with 'jquery.sap.require' but must be loaded by some other mean. The SAPUI5 framework includes both modules in its bootstrap files sap-ui-core.js and sap-ui-core-lean.js. The first one also embeds the SAPUI5 core functionality and needs no further modules. The second one only contains the two bootstrap modules and a require statement for the core. It is better suited for the development scenario described above (loading the modules separately).

If you create a new bootstrap file with the configuration UI and decide to include the jquery.sap.global or jquery modules, they always will be the first modules in the created file, and they will always be embedded. This ensures the availability of jQuery.sap.require.

Cyclic Dependencies

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 157

Sometimes, the functionality in two modules A and B might be interdependent. That means module A requires module B to execute and module B requires module A. We stated above that jQuery.sap.require ensures that the execution of a calling module doesn't continue until the required module has been loaded and executed. Taking this serious, cyclic dependencies could not be resolved but would lead to an endless series of requests (A->B->A->B->...).

This situation can be avoided by a workaround: As soon as a module A has been loaded and is about to execute, it is regarded as declared. So, when this module A embeds another module B which has not been loaded, module B will be loaded and executed. If B now again requires A, then the dependency resolution runtime will find that A has been declared already (despite the fact that its execution has not been finished yet) and simply returns. This workaround helps to break the endless loop, but it doesn't re-ensure the original promise of jQuery.sap.require.

Cyclic modules have to deal with that gap on their own. There are several ways/best practices how to do this:

● Variant 1: Merge A and BIf the conflicts can not be resolved easily, or if the modules are so highly related that they will be used together most of the time, then merging them into one module is the most simple solution.

● Variant 2: Interlaced Execution of A and BThis variant makes use of the fact that the module loading takes place exactly at the source location where the jQuery.sap.require function is executed. Let's assume that the content of modules A and B can be structured as follows:

// Module A, Part A.1

// Module Section A.1, does not depend on Module B and provides all code that module B depends on.

jQuery.sap.require("B");

// Module Section A.2, might depend on code in Module Section B.1

// Module B, Part B.1

// Module Section B.1, does not depend on Module A and provides all code that module A depends on.

jQuery.sap.require("A");

// Module Section B.2, might depend on code in Module Section A.1

Further assume (WLOG) that module A is loaded first. Then section A.1 will be executed and will be available to the outside world before the require('B') is executed. During the require, the framework will detect that B is not available yet, will load and execute it. The execution starts with section B.1 which succeeds as it does not depend on A. When the execution of B reaches the require('A') statement, the framework detects that A has been loaded already and continues without loading A again. But remember, that the code from section A.2 is not available yet. The execution of B however continues and succeeds as - by assumption - B.2 does not depend on A.2. Now, the first require('B') succeeds and returns and section A.2 will be executed. And it might use the code from section B.1.

Procedure and result are similar in the case that B is loaded first.

158 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.16.2 Resource Handling

The resource handling of SAPUI5 is separated in two parts - a client-side and a server-side resource handling. Both are not dependent on each other. Furthermore they are complementary.

The server-side mechanism is not required. This is an optional component which improves the client-server interaction (server-side locale fallback instead of client-side with multiple requests) and especially is used for the Eclipse IDE development to support modularized development of SAPUI5 application and libraries.

Client-side Resource Handling

On the client-side SAPUI5 provides the following mechanism for resources:

● Modularization Concept (!Require/Declare for JavaScript files)● Localization Concept (Resource Bundles)

Both concepts are loading additional resources from a server where this server might be any kind of web server (simple, Java, ABAP, ...). It does not depend on any server side technology.

Server-side Resource Handling

For the Java server and also the integration into the Eclipse IDE SAPUI5 provides a resource handler. This resource handler is aligned with the concept of the JavaServer Faces - Resource Handler:

● The default implementation must support packaging resources in the web application root under the path resources/<resourceIdentifier> relative to the web app root.

● Resources packaged in the classpath must reside under the JAR entry name META-INF/resources/<resourceIdentifier>

The SAPUI5 resource handler extends this concept to support standard and test-relevant resources. Therefore we package our resources into the following paths:

● resources/**Resources are all kind of JavaScript, CSS, Mimes, Resource Bundles, which are relevant for the runtime.

● test-resources/**Test resources are resources which are samples and only relevant for testing purposes e.g. the content of the SAPUI5 test suite.

Other additional features of the resource handler are:

● Theme fallback:If resources are not available for the current theme it automatically checks the base theme for such resources and returns this resource instead without returning a 404.

● Resource bundle fallback:Similar to the client-side mechanism for loading resource bundles but it negotiates the request on the server and returns the best found resource bundle instead without 404, e.g.:messagebundle_en_US.properties > messagebundle_en.properties > messagebundle.properties

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 159

Resource Servlet

For Java Servlet containers SAPUI5 provides a ResourceServlet which manages the access to SAPUI5 resources within the web application and the various UI libraries in the classpath. The following snippet shows how to enable the resource servlet for SAPUI5:

#!text/xml

<!-- ============================================================ --> <!-- SAPUI5 resource servlet used to handle application resources --> <!-- ============================================================ -->

<servlet>

<display-name>ResourceServlet</display-name>

<servlet-name>ResourceServlet</servlet-name>

<servlet-class>com.sap.ui5.resource.ResourceServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>ResourceServlet</servlet-name>

<url-pattern>/resources/*</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>ResourceServlet</servlet-name>

<url-pattern>/test-resources/*</url-pattern>

</servlet-mapping>

Before you can use it you need to make sure that the ResourceServlet is available in the classpath as JAR file.

Configuration

The resource handler is configured via context parameter which are defined in the web.xml. The following table gives an overview about configuration parameters:

Key Description

com.sap.ui5.resource.USE_CACHE flag to enable resource cache or not (default: "true")

com.sap.ui5.resource.MAX_AGE max age of resources in millis (default: "604800000" - 1 week)

com.sap.ui5.resource.ACCEPTED_ORIGINS list of accepted origins, e.g. * or *sap.corp,vesapui5.dhcp.wdf.sap.corp (default: empty)

com.sap.ui5.resource.DEV_MODE flag to enable the development mode (default: "false")

160 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Key Description

com.sap.ui5.resource.TEMPLATE_PATH template for the resource listing (default: "/templates/listing.html")

com.sap.ui5.resource.VERBOSE verbosity of the resource handler (default: "false")

com.sap.ui5.resource.REMOTE_LOCATION location which is used to proxy requests to for resources not being located locally (default: empty)

com.sap.ui5.resource.PREFER_REMOTE_LOCATION flag to prefer resolving the resource from the remote location before fallback to the classpath (default: false)

Configuration parameters are added as context parameters to the web.xml.

Development Mode

When starting to develop SAPUI5 controls and modules being located inside the servlet paths resources/ or test-resources/ it makes simplifies this development process by disabling the caching of such resources as well as enabling the resource browsing. To activate the development mode you need to add the following context parameter.

#!text/xml

<!-- BEGIN: DEV MODE --> <context-param> <param-name>com.sap.ui5.resource.DEV_MODE</param-name> <param-value>true</param-value> </context-param> <!-- END: DEV MODE -->

Resource Browsing

In case of having the development mode turned on you can browse resources via the resource browser:

● %SERVER_URL%/resources/ ● %SERVER_URL%/test-resources/

Tunneling a Remote Location

The ResourceServlet offers the opportunity to tunnel/proxy requests to another server providing SAPUI5 resources. This is the alternative instead for referring to SAPUI5 from remote location inside the bootstrap script tag to avoid cross domain issues. To activate this remote location tunneling/proxying you need to add the following context parameter to the web.xml of your application:

#!text/xml <context-param> <param-name>com.sap.ui5.resource.REMOTE_LOCATION</param-name>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 161

<param-value>http://%server%:%port%/sapui5</param-value> </context-param>

This will dispatch requests from resources/sap/ui/commons/Button.js to http://%server%:%port%/sapui5/resources/sap/ui/commons/Button.js.

If you are located behind a proxy and the remote location is outside your local network you can configure the proxy settings via the standard Java Networking and Proxy configurations by setting the system properties (for HTTP): http.proxyHost, http.proxyPort, http.nonProxyHosts, or (for HTTPS) https.proxyHost, https.proxyPort, https.nonProxyHosts of your Java runtime environment.

In general for the resources returned from the proxy the ResourceServlet is enabling caching. It by default uses the configured com.sap.ui5.resource.MAX_AGE to avoid to much load on the ResourceServlet.

Verify that a Resource was Retrieved from Remote Location

When in development mode it is possible to verify that a resource was retrieved from the desired remote location by checking the response header of the respective request. In this case the response header has an entry x-sap-ResourceUrl = remote resource URL, for example:

x-sap-ResourceUrl = http://%server%:%port%/sap/public/bc/ui5_ui5/resources/sap-ui-core.js

Resource Packaging

This section describes the resource packaing for web applications and Java modules which could be any kind of a JAR file (SAPUI5 UI library, ...) available in the classpath of the web application.

● For a web application this means you have to store the resources in the following way:

WebContent/ resources/ **/** test-resources/ **/**

● For the SAPUI5 UI libraries we store the resources in the following way:

META-INF/ resources/ **/** test-resources/ **/**

For custom JAR files you need to apply to this on your own.

OSGi Servlet Container

When running SAPUI5 as an OSGi Web Bundle and referencing the UI libraries as OSGi bundles you may need to know about a technical detail how SAPUI5 OSGi bundles are determined:

162 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● In the OSGi servlet container we extend the ResourceServlet by using an OSGi fragment which is responsible to add the OSGi flavor for the determination of UI libaries. Now the ResourceServlet is aware about the OSGi bundles and can search within the OSGi Servlet Container for UI libraries.

● The MANIFEST.MF of UI library JAR files contains a special entry which is used for the determination:

x-sap-ui5-ContentTypes: UILibrary

This is used by the OSGiResourceServlet to determine the relevant UI libraries.

SAPUI5 Library Location Used for Testing

If the SAPUI5 bootstrap tag contains src="resources/sap-ui-core.js", the SAPUI5 runtime libraries from the Eclipse plugin are used.

If you want to test your SAPUI5 application in Eclipse against a different SAPUI5 Library location, for example on the ABAP server when running in the SAP NetWeaver UI AddOn scenario, you can configure the ResourceServlet. For that, open the web.xml file located in the <WebContent folder name>/WEB-INF folder and configure the parameter com.sap.ui5.resource.REMOTE_LOCATION and com.sap.ui5.resource.PREFER_REMOTE_LOCATION of the ResourceServlet where the placeholders {protocol}, {host name}, {port number}, {path to UI5 library} are to be exchanged by the real protocol, host name, port number and path to the SAPUI5 library, see Resource Handling, section Tunneling a Remote Location.

<servlet> <display-name>ResourceServlet</display-name> <servlet-name>ResourceServlet</servlet-name> <servlet-class>com.sap.ui5.resource.ResourceServlet</servlet-class> </servlet> ... <!-- force to use the remote location --> <context-param> <param-name>com.sap.ui5.resource.PREFER_REMOTE_LOCATION</param-name> <param-value>true</param-value> </context-param> <!-- add the remote location for the UI5 libraries --> <context-param> <param-name>com.sap.ui5.resource.REMOTE_LOCATION</param-name> <param-value>{protocol}://{host name}:{port number}/{path to UI5 library}</param-value> </context-param>

1.1.3.16.3 Cache Buster

A cache buster allows the application to notify the browser to refresh the resources only when the application resources have been changed. Otherwise the resources can always be fetched from the browser's cache.

When you want to cache your resources permanently, you simply need to change the URL in the SAPUI5 bootstrap tag from resources/sap-ui-core.js to resources/sap-ui-cachebuster/sap-ui-core.js.

The cache buster mechanism allows to always put the SAPUI5 resources into the browsers cache until a UI library or a web application has been changed. The default behavior of the SAPUI5 resource handler is either to cache the

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 163

resources for a specific amount of time or alternatively in development mode it is using the 304/NOT MODIFIED mechanism to check the SAPUI5 resources for being up-to-date. Both mechanisms are not optimal in a final, productive scenario - that is the reason for the implementation of the cache buster mechanism. Applications, which want to use the cache buster mechanism have to explicitly decide to use it.

The cache buster mechanism is part of the resource servlet. In general requests to JavaScript resources can be handled via the cache buster mechanism. Typically this is used for the initial request for the bootstrap JavaScript:

#!text/html

<script type="text/javascript" id="sap-ui-bootstrap" src="resources/sap-ui-cachebuster/sap-ui-core.js" data-sap-ui-libs="sap.ui.core,sap.ui.commons,sap.ui.table" data-sap-ui-theme="sap_goldreflection"></script>

The bootstrap JavaScript will be included via the URL resources/sap-ui-cachebuster/sap-ui-core.js instead of resources/sap-ui-core.js.

Mechanism

The basic mechanism is implemented in the ResourceServlet. For the request to the bootstrap JavaScript it now serves a JavaScript file with the following content:

#!js

(function() { var sTimeStamp = '~20120716-0201~'; var sScriptPath = 'sap\x2dui\x2dcore.js'; var aScriptTags = document.getElementsByTagName('script'); for (var i = 0; i < aScriptTags.length; i++) { if (aScriptTags[i].src) { var iIdxCb = aScriptTags[i].src.indexOf('/sap-ui-cachebuster/'); if (iIdxCb >= 0 && aScriptTags[i].src.substring(iIdxCb + '/sap-ui-cachebuster/'.length) == sScriptPath) { var sBasePath = aScriptTags[i].src.substring(0, iIdxCb); sBasePath += '/' + sTimeStamp + '/'; window["sap-ui-config"] = window["sap-ui-config"] || {}; window["sap-ui-config"].resourceRoots = window["sap-ui-config"].resourceRoots || {}; window["sap-ui-config"].resourceRoots[''] = sBasePath; document.write('<script type="text/javascript" src="' + sBasePath + sScriptPath + '"></script>') break; } } }})();

This script basically ensures that the global SAPUI5 configuration variable (window["sap-ui-config"]) exists, without modifying any existing values. It defines the resource root of SAPUI5 (the location where SAPUI5 loads all JavaScript modules, controls and control related resources from). Finally, another script tag is added to the page that points to the real boostrap JavaScript. The new resource root and the request path to the bootstrap JavaScript now contain a timestamp. Additionally the cache headers of the reponses now look like the following:

Date: Mon, 16 Jul 2012 05:17:54 GMTExpires: Thu, 14 Jul 2022 05:17:54 GMTCache-Control: max-age=315360000, public

164 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

By default all cache buster resources will be cached for one year.

Request Flow

When using the cache buster mechanism, the first request must never be cached because it is being used to determine the timestamp / and to finally redirect to the correct script. The following list explains the flow:

● resources/sap-ui-cachebuster/sap-ui-core.js => NO_CACHE● resources/~201106210204~/sap-ui-core.js =>CACHE

Timestamp

If you are interested in the timestamp of the cache buster, you can grab it with the following request:

resources/sap-ui-cachebuster

The response is text/plain with such value: ~20120716-0201~

1.1.3.16.4 Application Cache Buster

The Application Cache Buster (short AppCacheBuster) is similar to the Cache Buster but is used for application resources.

Applications provide an index file (created on the fly) containing the last modified timestamps of all included files (scripts, properties – files which we load via XHR programmatically). Technically this file is a mapping between the request path (below the context path of the application) and the last modified timestamp.

The server in general caches all the above resources (not using the 304/not modified mechanism). For the index file we are using the 304/not modified mechanism to avoid to load when it has not been changed.

On the client-side we initially load this file of the application when enabled via configuration option sap-ui-appcachebuster and use this for the XHR requests. If the request path is contained in the above mentioned index file we simply add the timestamp as leading path segment to this request. If the timestamp doesn’t change the URL is unique and therefore it will be taken from cache. Once the file is modified the URL parameter will be changed and therefore loaded again from the backend.

The server has to delete the timestamp from this URL to lookup the file properly. For the Java applications SAPUI5 provides a AppCacheBusterFilter and for ABAP the logic is implemented in the ICF handler. Both backend implementations also generate the index file on-the-fly.

NoteThe Application Cache Buster does not work across application borders. If you require resources from another application they are not loaded via this mechanism.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 165

Application Cache Buster: Index File

Unlike the cache buster mechanism for runtime resources, the application files have an own timestamp for each file. Thus, the application provides the index file sap-ui-cachebuster-info.json. This file in JSON format includes all files that should use this mechanism. The index file looks as follows:

{ "mvc/MyMVC.view.js": "20120907134005", "mvc/MyMVC.controller.js": "20120907134005", "mvc/MyMVC.view2.js": "20120906113301", "mvc/MyMVC.controller2.js": "20120906113023"}

Application Cache Buster: Configuration

To activate the Application Cache Buster the configuration data-sap-ui-appCacheBuster="./" must be added to the bootstrap script of the application page:

<script id="sap-ui-bootstrap" src="resources/sap-ui-cachebuster/sap-ui-core.js" data-sap-ui-libs="sap.ui.core,sap.ui.commons,sap.ui.table" data-sap-ui-theme="sap_goldreflection" data-sap-ui-appCacheBuster="./"></script>

The parameter data-sap-ui-appCacheBuster is a string[] which means you can pass a list of base URLs for other applications. By default it should contain the base path of your local application.

These base URLs are used to load the index files. This allows to handle not only the local resources via the Application Cache Buster. Furthermore other applications could then also be handled.

Application Cache Buster: Request Flow

When using the Application Cache Buster mechanism, the first request must never be cached because it is being used to fetch the index file. The following list explains the flow:

1. http://myserver/myapp/sap-ui-cachebuster-info.json ⇒ NO_CACHE2. http://myserver/myapp/~201106210204~/mvc/MyMVC.view.js ⇒ CACHE

○ http://myserver/myapp/mvc/MyMVC.view.js ⇒ internally resolve to this URL

166 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Enable the Filter for Java Applications

To enable the server-side part of the Application Cache Buster mechanism the following filter needs to be configured in the web.xml:

<!-- ============================================================== --> <!-- AppCacheBuster Filter --> <!-- ============================================================== -->

<filter> <display-name>AppCacheBusterFilter</display-name> <filter-name>AppCacheBusterFilter</filter-name> <filter-class>com.sap.ui5.resource.AppCacheBusterFilter</filter-class> </filter> <filter-mapping> <filter-name>AppCacheBusterFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Application Cache Buster: Enhanced Concept

The first iteration of the Application Cache Buster only supports files which have been loaded via jQuery.ajax. The enhanced concept supports the transformation of URLs for jQuery.sap.includeScript, jQuery.sap.includeStyleSheet, and properties of the type sap.ui.core/URI. This ensures that the Application Cache Buster mechanism takes care about most of the URLs in a general way. Additionally the enhanced concept allows to register components or base URLs which are considered by the Application Cache Buster. This base URL is used to load the index file with the timestamp information.

Registration of external URLs

If you do not specify all the applications in the bootstrap configuration, you can also register them during runtime. To register additional locations, use the following API:

sap.ui.core.AppCacheBuster.register("/sap/bc/my/other/component");

Avoid handling of specific URLs

To avoid handling of specific URLs, you can override the default behavior as follows:

sap.ui.core.AppCacheBuster.handleURL = function(sURL) { return sURL !== "my/specific/url";};

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 167

1.1.3.17 Control Devlopment Topics

The following sections introduce control development topics:

● Developing UI5 Controls in JavaScrip● Handling Events in Controls● Writing a Control Renderer● Focus Handling● Item Navigation● Right-to-Left Support

1.1.3.17.1 Developing UI5 Controls in JavaScript

The following sections explain how to create new controls in JavaScript on the fly, so-called notepad controls). For this basic development approach you do not need to define libraries or run generation steps. You can extend existing controls and create completely new controls.

This functionality is not restricted to controls: You can also create or extend arbitrary objects derived from sap.ui.base.Object.

Technically, the resulting controls are not different from controls developed with SAPUI5 tools.

Notepad Controls vs. Eclipse-based Controls

Notepad controls have the advantage that you create them very quickly without tools, build, or dependency overhead. You can create them, for example, inline within an application. All JavaScript can be in one file and the application CSS, which may be present anyway, contains the required styles. So notepad controls are a very light-weight approach, but still offering all the features of a real SAPUI5 control.

The control can, however, not be reused easily from different locations and applications: There is no formal way to address it and there is no package which you can reference to import the control. Also, if the control has to support multiple themes and you want to style it by using SAPUI5 theme parameters which are editable in the Theme Editor, if the right-to-left version of the styles should be generated automatically, the Eclipse-based tools offer everything with their integrated build. Checks are not run on a notpad control and no JSDoc documentation can be created.

If a control is supposed to be reused in different applications or by people who do not closely communicate with the control developer, and if a control is more complex than a very basic control, we recommend to consider formally creating a Control Library and using the SAPUI5 Eclipse to create the controls.

168 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Basic Concept: Extend Method

The extend() method is available on all controls (and the base classes) and is used to define a new subclass. The following code creates a new control from scratch:

sap.ui.core.Control.extend(...)

The following code creates a new control which inherits from Button:

sap.ui.commons.Button.extend(...);

The function has the name and the definition of the new control type as parameters. The definition contains information about the control API, that is, the properties, aggregations, events and so on, as well as the implementation of the control methods. In addition to that it provides the function that creates the control's HTML structure.

NoteSAPUI5 creates some methods automatically, such as the getters and setters for properties and aggregations or methods for attaching/detaching event handlers. You can in fact develop a non-default implementation that provides more or other functionality.

A First Basic Example

The following code creates a simple control with a name property. The purpose of the control is to render the text "Hello <name>":

#!js

sap.ui.core.Control.extend("my.Hello", { // call the new Control type "my.Hello" // and let it inherit from sap.ui.core.Control metadata : { // the Control API properties : { "name" : "string" // setter and getter are created behind the scenes, // including data binding and type validation } },

renderer : function(oRm, oControl) { // the part creating the HTML oRm.write("<span>Hello "); oRm.writeEscaped(oControl.getName()); // write the Control property 'name', with XSS protection oRm.write("</span>"); }});

The new control is ready for use now. It can be instantiated and displayed as usual:

#!js

new my.Hello({name:"UI5"}).placeAt("content");

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 169

Technical Background

A control is an object that defines the appearance and the behavior of a screen area.

A control has properties, such as "text" or "width". These properties modify the appearance or relate to the data displayed by the control. A control can aggregate other controls: It serves as a sort of container or layout control where the application can add child controls or as a composite control if the control adds child controls and just reuses available components. A control can also have associated controls that are not part or children of this control, but rather loosely related.

A control can fire well-defined events. The meaning of these events typically relates to the control's purpose and functionality and is on a semantically higher level than "click" or other browser events. Examples for such events are triggerSearch in a search field or collapse in a panel.

This information is defined in the control metadata which is the public API of the control and can be queried at runtime and also contains useful information for runtime features like data binding and type validation checks.

Control Base Class

sap.ui.core.Control is the base class of all SAPUI5 controls. Specific controls can either inherit from this base class or from another control to inherit and extend the functionality. sap.ui.core.Element is the base class of sap.ui.core.Control. Elements can be like parts of controls or rather configuration packages for parts of controls, but in general they are not meant for standalone use and do not have their own renderer. The controls that use these elements do the rendering, for example, a ListItem element is rendered by the ListBox control. Whatever this page documents about controls, it usually also applies to Elements (but not to the renderer).

Control Name

The control name is a string that consists of Library name and control name. For both names, you use letters and dots for separation where you should avoid dublicates regarding other JS entity namings within the same application. It is also possible that you omit the library name and call the control Square. You would generally do this if you there is no need for assigning the control to a library which shall also be available

for developing other applications. When you write a control to be reused by others, a unique Library name is recommended: sap.byd.Square.

Control Metadata

For the creation of new controls, the metadata block defines the properties, aggregations, events etc. of the control. Depending on the control, not only the number of entries, but also their amount of information can be small or quite extensive.

For the use case class extension - where the classes do not inherit from control or Element but from a more generic class - these control-specific settings are not available. For more information, read chapter "Object

170 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Metadata and Implementation" below. Note that all the object metadata described there is also applicable for extending controls.

Properties

A property is defined by at least its name and its type. Additionally, the default value of the property can be defined. So the available settings are:

● type: The data type of the control property. Automatic type validation is done in the UI5 core. Examples for valid types are:

○ string for a string property (default)○ int or float for number properties○ int[] etc. for arrays○ sap.ui.core.CSSSize for a custom-defined type

● defaultValue: The default value this property should have when the application does not set a value. If no default value is given, the property initially has value undefined.

So property definitions can look like this:

#!js

properties: { "title" : "string", // a simple string property, default value is {{{undefined}}} "buttonText" : {defaultValue: "Search"}, // when no type is given, the type is {{{string}}} "showLogoutButton" : {type : "boolean", defaultValue : true}, // a boolean property where a default value is given "width" : {type : "sap.ui.core.CSSSize", defaultValue : "50px"} // a CSS size property where a default value is given}

From the technical point of view, you could also define the "group" (the category into which this property falls), but this has no impact outside of development tools which may want to display and group the properties of your control.

Once such a property is defined, the control automatically has the methods setShowLogoutButton and getShowLogoutButton, which are responsible for storing the data. You can give your own custom definition for either of them, you have to call the generic property setter/getter setProperty/ getProperty then.

Events

Events are specified by the event name only. In many cases there is nothing to configure about them, so just give an empty object:

#!js

events: { "logout": {}}

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 171

As an advanced feature, controls can enable events to be interrupted by the application, when usually the control would immediately execute an action. For example, if a Tab control fires a "close" event and wants to enable the application to cancel the closing. To do so, the control needs to set the enablePreventDefault property of the Event to "true" (and check the return value after firing the event):

#!js

events: { "close": {enablePreventDefault : true} }

For every defined Event, methods for registering, de-registering and firing the event are created, in this case: attachLogout, detachLogout, fireLogout.

Aggregations and Associations

Aggregations and associations are again defined by their name, along with an object that can have the following information:

● type: This should be a type which is subclass of Element or control (default is sap.ui.core.control)● multiple: Whether it is a 0..1 aggregation or a 0..n aggregation (default is "true", which means 0..n, for

aggregations and "false" for associations)● singularName: For 0..n aggregations, the aggregation name typically is plural, but certain methods are

created where the singular form is required (for example, addWorksetItem} for the "worksetItem' s'" aggregation).

If only the type needs to be set, you can just give it as a string instead of the configuration object.

One example:

#!js

aggregations: { "acceptButton" : "sap.ui.commons.Button", // if only type is given, no object is required "content" : {singularName: "content"}, // default type is "sap.ui.core.Control", // which is appropriate for generic containers "worksetItems" : {type : "sap.ui.ux3.NavigationItem", multiple : true, singularName : "worksetItem"} // a fully specified aggregation}

Multiple methods are created, depending on the multiplicity, for example: getWorksetItems, insertWorksetItem, addWorksetItem, removeWorksetItem, removeAllWorksetItems, indexOfWorksetItem, destroyWorksetItems

If you want to mark one aggregation as default aggregation (in order to be able to omit the aggregation tag in XMLViews), you can do this by setting the defaultAggregation property to the name of the aggregation as follows:

aggregations: { "content": {singularName: "content"} // default type is "sap.ui.core.Control", multiple is "true"

172 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

},defaultAggregation: "content"

Methods

You can add any method to a new control by providing the implementation, without adding it to the metadata. By convention, all methods are public, exception here is if their name starts with an underscore, or if it is one of the special method types listed below.

Other controls and the application may only call public methods and the control needs to ensure they remain compatible. Though, there are no technical rules that prevent a call of private methods.

Public methods are the generated getter/setter methods for properties etc.

Control Implementation

After the metadata is defined, you can add any method implementations to your new control. In general, the method names can be chosen freely, but note that some method names must be avoided:

● Names of methods that are provided by a super class (or will be provided...). Your implementation overwrites their's, that's the deal with inheritance.

● set.../get.../insert.../add.../remove.../indexOf... may collide with setters/getters for properties or aggregations you defined

● attach.../detach.../fire may collide with methods created for events

As long as you do not introduce the respective property or so, you are of course safe to use a certain "set..." method name.

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: Is a special name that holds either● the function that creates the Control's HTML or● a complete structure that contains this function and more (for more information see below)

Normal Methods

Any method, either public or private, is just appended to the implementation object. The convention is that private methods that may not be called from outside a Control start with an underscore. All other methods are considered public as long as they do not belong to the special method types listed below.

#!js

divide: function(x, y) { // a public method of the Control

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 173

if (this._checkForZero(y)) {

throw new Error("Second parameter may not be zero");

}

return x / y;

},

_checkForZero: function(y) { // private helper method

if (y === 0) {

return true;

}

return false;

}

init() Method

The init() method is invoked by the SAPUI5 core for each control instance right after the constructor. Use this to set up things like internal variables or sub-Controls of a composite. Note that any values given in the control constructor are NOT yet available! This is intentional to prevent the typical error where controls would only work fine when values are set initially, but not when values are changed later. This method is considered private and only to be called by the SAPUI5 core.

#!js

init: function() {

this._bSearchHasBeenTriggered = false;

this._oSearchButton = new sap.ui.commons.Button(this.getId() + "-searchBtn", {text: "Search"});

}

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 SAPUI5 core. So it is sufficient to simple add a handler method, and it will automatically be called. Additionally, the SAPUI5 core fires events with a richer semantic meaning, so control developers do not need to check so many keycodes etc. The name of these events starts with "sap", they are defined in jquery.sap.events.js. One example for such an event is sapnext which is triggered by "arrow down" or "arrow right" (or "arrow left" in right-to-left mode). Therefore, multiple checks would be required to check whether the user wants to navigate to the next item. The

174 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

sapnext event takes over all these checks. The "evt" object given to the handler method contains more information. These methods are considered to be private and may only be called by the UI5 core.

#!js

onclick: function(evt) {

alert("Control " + this.getId() + " was clicked.");

},

onsapnext: function(evt) {

// navigate to next item, an arrow key was pressed

...

}

Renderer Method / Object

This 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. The RenderManager is used as a sort of "writer" - it is a collector for string fragments and takes care of efficiently concatenating them and placing them into the appropriate DOM position.

#!js

renderer: function(rm, oControl) { oRenderManager.write("<div>", oControl.getText(), "</div>");}

All the features and rules of writing the control Renderer in normal control development apply here as well. The control must, for example, only have one HTML element as root node and inside this node oRenderManager.writeControlData(oControl); must be called, so this root element can be marked as UI5 control root and the ID of the control is written.

The newly created renderer type will inherit from the renderer of the parent control. So if your new control extends TextField, the given function will be added to a class that inherits from sap.ui.commons.!TextFieldRenderer (and will have access to that one's other functions).

If an existing renderer should be used without modification, you can give the name of this renderer class:

#!js

renderer: "sap.ui.commons.ButtonRenderer"

However, a normal control renderer can also override or implement methods from its renderer superclass. Or just separate out some helper functions.

This is possible as well here, but in this case these methods need to be packed together into an object, so the extend method knows they should all go into the control renderer. The main rendering method is called "render" -

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 175

just like in a normal control renderer. The keyword "this" actually refers to the Control Renderer type here, so it is used to access the other methods:

#!js

renderer: {

render: function(rm, oControl) {

rm.write("<div>");

rm.writeEscaped(this.square(oControl.getValue()));

rm.write("</div>");

},

square: function(value) {

return value * value;

}

}

Object Metadata and Implementation

For extending plain objects that are not elements or controls, only the following metadata is available (it is also available for extending controls, though!):

● "interfaces": an optional array of strings that denotes the implemented interfaces● "publicMethods": an optional list of methods that should be part of the public API. By default all methods that

do not start with an underscore are public.● "abstract": an optional flag to mark the type as abstract● "final": an optional flag to mark the type as final

Regarding the implementation, all methods given outside the metadata are attached to the new type. There is one reserved method name: "constructor". The function given under this name will be the constructor of the new class. While technically you can also define a constructor for new elements and controls, you should not do it. Your control may otherwise break in certain scenarios like with list bindings, or may break later when UI5 extends the constructor signature.

Examples for Creating New Controls

To create an entirely new control type, you extend the sap.ui.core.Control class. You define the control API and the implementation from scratch.

176 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Simple "Square" Control

A "Square" control that is rendered as a red square and has some text written inside and pops up an alert when clicked, looks like this:

#!js

sap.ui.core.Control.extend("Square", { // call the new Control type "Square" and let it inherit // from sap.ui.core.Control

// the Control API: metadata : { properties : { // setter and getter are created behind the scenes, // incl. data binding and type validation "text" : "string", // in simple cases, just define the type "size" : {type: "sap.ui.core.CSSSize", defaultValue: "200px"} // you can also give a default value and more } },

// the part creating the HTML: renderer : function(oRm, oControl) { // static function, so use the given "oControl" instance // instead of "this" in the renderer function

oRm.write("<div"); oRm.writeControlData(oControl); // writes the Control ID and enables event handling - important! oRm.addStyle("width", oControl.getSize()); // write the Control property size; the Control has validated it // to be a CSS size oRm.addStyle("height", oControl.getSize()); oRm.writeStyles(); oRm.addClass("mySquare"); // add a CSS class for styles common to all Control instances oRm.writeClasses(); // this call writes the above class plus enables support // for Square.addStyleClass(...)

oRm.write(">"); oRm.writeEscaped(oControl.getText()); // write another Control property, with protection // against cross-site-scripting oRm.write("</div>"); },

// an event handler: onclick : function(evt) { // is called when the Control's area is clicked - no event registration required alert("Control clicked! Text of the Control is:\n" + this.getText()); } });

The control definition and implementation is finished now, but some styling remains to be done.

The visual appearance could have been written to the control HTML in the renderer method, just like the instance-specific width and height was written. But it is better to define style that is common to all control instances in a CSS file, or at least in a <style> tag, so it only needs to be written once and it can be easily modified by the application.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 177

So we add a grey background, a red border and some alignment stuff:

#!css

<style> .mySquare { /* style the CSS class that has been written by the renderer method */ display: inline-block; /* enable squares to appear next to each other within one line */ border: 1px solid red; /* add some border, so the square can actually be seen */ background-color: #ddd; padding: 8px; text-align: center; -moz-box-sizing: border-box; /* consider padding+border part of the width/height */ box-sizing: border-box; }</style>

Use

This custom control can now be used like any SAPUI5 control:

#!js

var myControl = new my.Square({text:"Hello", size: "100px"});myControl.placeAt("content");

Simple Container Control

A container control that can hold arbitrary child controls and renders them in a row, with a colored box around each child, looks like this:

#!js

sap.ui.core.Control.extend("ColorBoxContainer", { // call the new Control type "Square" // and let it inherit from sap.ui.core.Control

// the Control API: metadata : { properties : { // setter and getter are created behind the scenes, // incl. data binding and type validation "boxColor" : "string" // the color to use for the frame around each child Control }, aggregations: { content: {singularName: "content"} // default type is "sap.ui.core.Control", multiple is "true" } },

// the part creating the HTML: renderer : function(oRm, oControl) { // static function, so use the given "oControl" instance // instead of "this" in the renderer function

178 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

oRm.write("<div"); oRm.writeControlData(oControl); // writes the Control ID and enables event handling - important! oRm.writeClasses(); // there is no class to write, but this enables // support for ColorBoxContainer.addStyleClass(...) oRm.write(">");

var aChildren = oControl.getContent(); for (var i = 0; i < aChildren.length; i++) { // loop over all child Controls, // render the colored box around them oRm.write("<div>"); oRm.addStyle("display", "inline-block"); oRm.addStyle("border", "3px solid " + oControl.getBoxColor()); // specify the border around the child oRm.writeStyles(); oRm.write(">");

oRm.renderControl(aChildren[i]); // render the child Control // (could even be a big Control tree, but you don't need to care)

oRm.write("</div>"); // end of the box around the respective child }

oRm.write("</div"); // end of the complete Control } });

There is no additional CSS required, as the Control has no appearance on its own, but basically consists of its children and the boxes around them.

Use

This strange container control can now be used like any SAPUI5 container:

#!js

var btn = new sap.ui.commons.Button({text:'Hello World'}); var tf = new sap.ui.commons.TextField({value:'edit text here'});

var container = new ColorBoxContainer({ boxColor: "#ff7700", content:[ btn, tf ]}); container.placeAt('content');

Examples for Extending Existing Controls

The following sections are examples of extending existing controls.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 179

Extendig the Button with an Additional Event

Let's build a new control, named "HoverButton" that is just like the normal button, but fires a "hover" event in addition when the mouse enters its area.

#!js

sap.ui.commons.Button.extend("HoverButton", { // call the new Control type "HoverButton" // and let it inherit from sap.ui.commons.Button metadata: { events: { "hover" : {} // this Button has also a "hover" event, in addition to "press" of the normal Button } }, // the hover event handler: onmouseover : function(evt) { // is called when the Button is hovered - no event registration required this.fireHover(); },

renderer: {} // add nothing, just inherit the ButtonRenderer as is; // In this case (since the renderer is not changed) you could also specify this explicitly with: renderer:"sap.ui.commons.ButtonRenderer" // (means you reuse the ButtonRenderer instead of creating a new view });

Use

Use this ToggleButton in an application just like a regular button - but you can now attach a handler to the "hover" event.

#!js

var myControl = new HoverButton("myBtn", { text: "Hover Me", hover: function(evt) { alert("Button " + evt.getSource().getId() + " was hovered."); } });

myControl.placeAt("content");

Extending the TextField Rendering

This example builds a new control type that inherits from TextField and has all its features, but changes the rendering to be very highlighted with yellow background.

The control API and even the "render" method can be inherited as is. You only overwrite the renderInnerAttributes method of the TextFieldRenderer:

#!js

sap.ui.commons.TextField.extend("HighlightField", { // call the new Control type

180 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

"HighlightField" // and let it inherit from sap.ui.commons.TextField

renderer: { // note that NO render() function is given here! The TextField's render() function is used. // But one function is overwritten: renderInnerAttributes : function(oRm, oTextField) { oRm.addStyle('background-color', '#ffff00'); // this change could also be done with plain CSS!! // But you get the idea... } } });

Use

Use this HighlightField in an application just like a regular TextField. It has all the normal features and behavior. But it has the modified rendering.

#!js

var myControl = new HighlightField({value:"Highlighted editing"});myControl.placeAt("content");

1.1.3.17.2 Handling Events in Controls

Two types of events exist in SAPUI5 applications:

● Events fired by the browser; these events are well-known, for example "click" and "blur"● Events fired by SAPUI5 controls; these events are usually semantically richer and related to the control

functionality; for example a browser-level "click" on the respective icon in a panel header that triggers a "maximize" or "minimize" event

Applications can listen to both types of events.

The following sections describe how control implementations can use browser events (type 1) to implement their behavior and to eventually fire control events (type 2).

Registering for Browser Events

When a control needs to react on browser events, there are two ways to register for the events, the "standard" way and an "optimized SAPUI5" way:

● Explicitly register for browser events on certain DOM elements, typically using jQuery.bind() (using the respective browser methods like addEventListener would also be possible).The event registration must be done in the onAfterRendering method of the Control, so the event binding is always repeated after the control is re-rendered (new DOM elements are created and old ones are discarded). Furthermore, to prevent memory leaks, the event binding must be removed (with jQuery.unbind()) in the "onBeforeRendering" method and in the "exit" method (which is called before the control is destroyed).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 181

○ Pro:ANY type of browser event can be handledWorks exactly like in any web page or jQuery-based web application

○ Con:Quite some code required to do the binding and unbinding of the event handlerRegistering many event handlers can affect performance

Example:

MyControl.prototype.onAfterRendering = function() {

this.$().bind("click", jQuery.proxy(this.handleClick, this)); // could also be: jQuery.sap.byId(this.getId).bind("click", jQuery.proxy(this.handleClick, this)); }

MyControl.prototype.onBeforeRendering = function() { this.$().unbind("click", this.handleClick); }

MyControl.prototype.exit = function() { this.$().unbind("click", this.handleClick); }

MyControl.prototype.handleClick = function(oEvent) { // do something... }

● Just implement the event handler for certain "common" event types, using a name convention for the handler method.SAPUI5 automatically registers event handlers for a list of commonly used event types on the root element of a complete tree of SAPUI5 controls. If the respective event occurs anywhere in the tree and the respective Control implements the on<eventName> method, this method is invoked as if it had been registered with jQuery.bind().

○ Pro:Saves Control codeSaves number of event handler registrations in the DOMSaves evet handler registrations and deregistrations executed on every re-rendering

○ Con:Only works for a certain (comprehensive) list of events

Example:

MyControl.prototype.onclick = function(oEvent) { // do something...}

As you can see from these examples, the SAPUI5 event handling functionality saves code.

List of Supported Browser Events

The following events are available to be handled by just implementing an "on<eventName>" method (list is also available via API, see JSDoc of jQuery.sap.ControlEvents):

182 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● click● dblclick● dragend● dragenter● dragleave● dragover● dragstart● drop● focusin● focusout● keydown● keypress● keyup● mousedown● mouseout● mouseover● mouseup● paste● select● selectstart

Pseudo Events

In addition to the native browser events listed above, SAPUI5 also creates so-called "pseudo events" which are semantically enriched, but can also be handled implementing an on<eventName> method. So they "feel like" browser events (but they cannot be used with jQuery.bind()).

These events help avoiding additional checks for modifier keys in the event handler or checking for certain keycodes.

The complete documentation of these events can be found in the JSDoc of jQuery.sap.PseudoEvents. The list is as follows:

● sapbackspace● sapbackspacemodifiers● sapbottom● sapcollapse● sapcollapseall● sapcollapsemodifiers● sapdecrease● sapdecreasemodifiers● sapdelayeddoubleclick● sapdelete● sapdeletemodifiers● sapdown

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 183

● sapdownmodifiers● sapend● sapendmodifiers● sapenter● sapentermodifiers● sapescape● sapexpand● sapexpandmodifiers● saphide● saphome● saphomemodifiers● sapincrease● sapincreasemodifiers● sapleft● sapleftmodifiers● sapnext● sapnextmodifiers● sappagedown● sappagedownmodifiers● sappageup● sappageupmodifiers● sapprevious● sappreviousmodifiers● sapright● saprightmodifiers● sapselect● sapselectmodifiers● sapshow● sapskipback● sapskipforward● sapspace● sapspacemodifiers● saptabnext● saptabprevious● saptop● sapup● sapupmodifiers

1.1.3.17.3 Writing a Control RendererFor control rendering purposes, the following three classes are relevant:

● The control class - the control that is to be rendered● The RenderManager class - responsible for injecting the generated markup into the DOM and offering helper

functionality

184 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● The renderer class - the base class of all control renderers

Control Class sap.ui.core.Control

In general, a control is made up of its properties, events, aggregations, associations, and methods. Together, these parts define the behavior of a Control. The following information is relevant for the appearance and data of the control: properties, associations, and aggregations. This information can be accessed directly with get and set methods of the control during the render() method.

Property Access:

// var oValue = oControl.get<Property>();// for example for the 'text'-propertyvar oValue = oControl.getText();

1..1 Aggregation Access:

// var oAggregation = oControl.get<Aggregation>();// for example for content-aggregationvar oAggregation = oControl.getContent();

1..n Aggregration Access:

// var aAggregations = oControl.get<Aggregation>s();// for example for rows-aggregationvar aAggregations = oControl.getRows();

Association Access:

// var sAssociatedControlId = oControl.get<Association>();// for example labelFor-associationvar sAssociatedControlId = oControl.getLabelFor();

RenderManager Class sap.ui.core.RenderManager

The RenderManager is responsible for injecting the generated markup into the DOM. It takes a control, determines and loads the corresponding renderer, and finally delegates the rendering of the control to the renderer. It also offers helper functionality for rendering purposes as follows:

Method Description

write() Writes string information to the HTML

writeControlData() Writes the ID and the recognition data of the control to the HTML

renderControl() Converts the specified control into HTML representation and adds it to the HTML. Use this for rendering child controls.

For further details, see the JSDoc of the RenderManager.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 185

Renderer Class sap.ui.core.Renderer

The Renderer implements the static render method that is called when a control is added to the DOM. The RenderManager executes the render method on the corresponding Renderer for the control to be rendered, and passes the reference to itself and the control.

The following code snippet shows the implementation of a simple renderer:

/** * This module provides the renderer for the MyControl control */

jQuery.sap.declare("sap.ui.myuilib.MyControlRenderer");

/** * @class MyControl renderer. * * @author SAP - TD Core UI&AM UI Infra * @version @version@ * @static */

sap.ui.myuilib.MyControlRenderer = {};

/** * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}. * * @param {sap.ui.core.RenderManager} oRenderManager The RenderManager that can be used for writing to the RenderOutputBuffer. * @param {sap.ui.core.Control} oControl An object representation of the control that should be rendered */

sap.ui.myuilib.MyControlRenderer.render = function(oRenderManager, oControl) {

// write the HTML into the render manager oRenderManager.write("<span "); oRenderManager.writeControlData(oControl); oRenderManager.write(" class=\"sap-ui-myuilib-MyControlRenderer\" "); oRenderManager.write("></span>");

};

Prevention of Cross-Site Scripting (XSS)

You can find some basic facts about Cross-Site Scripting (XSS).

XSS in SAPUI5 Controls

You must ensure that an attacker cannot inject script code into an application page as it runs in a user's browser. From a controls perspective, this means prohibiting controls from writing any scripts to the page that comes from the application, or might have come from business data saved by a different user. This is achieved by a combination of two measures:

186 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● ValidationThe validation of typed control properties means that as soon as a control property has a type other than string, the Core validates the value against this type when the application sets it. In this way, an int is always guaranteed to be an int, and a sap.ui.core/CSSSize is a string representing a CSS size (and not containing a script tag). This is also the case for enumerations and control IDs. The control renderer can rely on this check when writing the HTML.

● EscapingEscaping of string control properties and any other values coming from the application. This is the responsibility of the control developer when creating the renderer. The RenderManager and the Core offer helper methods for this (see below).

Avoiding XSS for your New Renderer

To ensure maximum security for your new renderer, follow the steps described below:

● Use the type sap.ui.core/CSSSize instead of string (or sap.ui.core/string) for control properties that refer to a CSS size.The more general rule is to use the most specific type for control properties that is available.

● If the value of a string property is written to the HTML, it must be escaped using one of the helper methods:

○ For writing plainly to the HTML, use writeEscaped(oControl.getSomeStringProperty()) instead of just write(...).

○ For writing attributes, use writeAttributeEscaped("someHtmlProperty", oControl.getSomeStringProperty()) instead of just writeAttribute(...).

○ For any usages of string properties where the above is not possible, use jQuery.sap.escapeHTML(oControl.getSomeStringProperty()) to escape the string and then process it further.

● Carefully check the HTML coding you are writing and consider whether any application value might make its way to the HTML.

○ Check where the variable values come from (can the application set its value directly, or only decide which of certain hardcoded values are used?).

○ Parameters in method calls of controls are (currently) not validated by the Core, so values given there are candidates for extra escaping.

○ Always keep in mind that XSS can happen anywhere and anytime in CSS classes, or in styles, for example.

1.1.3.17.4 Focus Handling

Each of the controls provided by the SAPUI5 framework has its own behavior for focus handling, depending on the functionality that is provided by the control. The highest level of complexity is reached in the case of complex controls and their embedded content.

For custom development of controls, the core of the framework provides mechanisms for observing the moving focus in an application page and preserves this information for refocusing elements after (re-)rendering. Furthermore, the focus triggers event firing. Due to the high degree of flexibility in control rendering, it may be necessary to implement functionality tailored to the control's inner workings. The following sections provide some insights into how to tailor this functionality.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 187

The framework provides helper functions for implementating focus handling.

Implementing Focus Handling When Developing Controls

The base class for all elements (Element.js) provides four methods to help you implement focus handling:

● Element.getFocusDomRef()● Element.focus()● Element.getFocusInfo()● Element.applyFocusInfo(oFocusInfo)

Element.getFocusDomRef()

Once a visible element is rendered, it has a Document Object Model (DOM) representation. The root DOM node can be accessed by using the method getDomRef() on the element. The root DOM node is the default focused DOM node. After rendering, the framework asks the control for its focus DOM node by using the getFocusDomRef() method. If the root DOM node does NOT represent the element that should have the focus, you have to return another DOM node by overriding the getFocusDomRef() method.

Element.focus()

The focus() method sets the focus on the element. This is done using the focus DOM node.

Element.getFocusInfo()

With some controls, it is even more difficult to apply the focus once the control has been re-rendered. Controls such as lists have their own internal focus handling, which sets the focus on the different items. A data table moves the focus over a matrix of cells. The requirement is that a control can apply the focus to its exact previous position after re-rendering. To provide this functionality, you override the getFocusInfo() method, and serialize the focus state into a JSON object and return it. Before rendering, the render manager calls this method for the element instance and stores this information for future use. After rendering, it calls the method applyFocusInfo() (see next method) and passes back this serialized object. The cursor position of a TextField control, for example, can also be stored in such an object.

188 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Element.applyFocusInfo(oFocusInfo)

The applyFocusInfo() method applies the focus to the element after re-rendering. You use this method if different behavior is expected for the element. Note that the default implementation sets the focus as it is implemented in the focus() method (see above).

Example

In our example, a control usually sets the focus on the second child node of its root node. In this case, you would simply override the getFocusDomRef() method.

sap.ui.commons.<SampleControl>.getFocusDomRef = function() { return this.getDomRef().firstChild.nextSibling;}

Another control generally sets the focus back to the element that previously had the focus. Therefore, it overrides the methods getFocusInfo and applyFocusInfo.

sap.ui.commons.<SampleControl>.getFocusInfo = function() { return {id:this.getId(),idx:this.<myFocusElementIndex>};}

sap.ui.commons.<SampleControl>.applyFocusInfo = function(oFocusInfo) { var oDomRef = this.getDomRef(); if (oDomRef) { this.<myFocusElementIndex> = oFocusInfo.idx; this.focus(); }}

Convenience Functionality

In addition to the automatic focus handling provided by the interaction between the render manager and the element instance, further focus-related functionality is available in sap.ui.util.Dom:

Dom.focus(oDomRef)

focus(oDomRef) can be used to focus a particular DOM element. This could be useful in the abovementioned custom focus handing scenario, for controls that cannot be handled by the default behavior of the focus() method or delegates such as ItemNavigation.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 189

Dom.hasFocus(oDomRef)

hasFocus(oDomRef) focuses a particular DOM element. It returns true if focusing could be performed and false if not, for example, because the element status was invisible.

NoteMethod naming may change in the future.

Dom.refocus(oDomRef)

refocus(oDomRef) refocuses a particular DOM element. This might be necessary for screen readers, for example, if the element is not read correctly.

Dom.getActiveElement()

getActiveElement() returns the active element (the currently focused element) of the document, if there is one. This information is also used by automatic focus handling during the re-rendering as described above.

1.1.3.17.5 Item Navigation - Supporting Keyboard Handling in List-like Controls

One common pattern for keyboard navigation is the item navigation in lists. The UI development toolkit for HTML5 therefore provides a helper class sap.ui.core.delegate.ItemNavigation that implements this functionality. It is intended to be used as a delegate for the keyboard events occurring inside the using control.

Each control that needs the ability to navigate with arrow keys over a one dimensional list of DOM nodes can use this delegate.

The delegate hooks into the browser events for arrow up/down/left/right, page up/down and home/end keys. With a list of DOM nodes provided by the control it sets the focus to the right DOM node in the list while handling the events.

In order to use this item navigation handling, the control needs to provide a DOM node that surrounds all DOM nodes of the items as well as a list of all the DOM nodes of the items themselves. The surrounding DOM node should initially get the focus when the control is entered to ensure the ItemNavigation delegate can do proper focus handling.

Via the methods setCycling the developer can choose whether the focus automatically moves to the top after the end of the list was reached. The page up/down keys will only work if the control developer sets a page size via setPageSize method on the delegate.

190 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Some controls also have one currently selected item in the list that initially should get the focus when the control is entered (again). With the setSelectedIndex method the control can specify such a preselected item for the delegate. If no selected index is given the first item will get the focus when entering the control.

If the control needs to be triggered before it will be focused by the item navigation, it can handle the events BeforeFocus respectively AfterFocus, to do e.g. preparation tasks for the controls visibility etc.

Using this delegate will save your control about 100 lines of JavaScript code for keyboard handling.

If you like you can still react on the events handled by the delegate in your control.

Integrating the ItemNavigation in your Control

A delegate should be applied in the onAfterRendering hook of a control and besides that should be applied only once:

sap.ui.commons.ListBox.prototype.onAfterRendering = function () { //Collect the dom references of the items var oFocusRef = this.getDomRef(), aRows = oFocusRef.getElementsByTagName("TR"), aDomRefs = []; for (var i=0;i<aRows.length;i++) { aDomRefs.push(aRows[i].firstChild); } //initialize the delegate add apply it to the control (only once) if (!this.oItemNavigation) { this.oItemNavigation = new sap.ui.core.delegate.ItemNavigation(); this.addDelegate(this.oItemNavigation); }

// After each rendering the delegate needs to be initialized as well.

//set the root dom node that surrounds the items this.oItemNavigation.setRootDomRef(oFocusRef);

//set the array of dom nodes representing the items. this.oItemNavigation.setItemDomRefs(aDomRefs);

//turn of the cycling this.oItemNavigation.setCycling(false);

//set the selected index this.oItemNavigation.setSelectedIndex(this.getSelectedIndex());

//set the page size this.oItemNavigation.setPageSize(this.getVisibleItems()); };

Ensure that the delegate is also correctly removed after the control is destroyed. Otherwise memory will leak because DOM nodes are still referenced by the delegate.

sap.ui.commons.ListBox.prototype.destroy = function() { if (this.oItemNavigation) { this.removeDelegate(this.oItemNavigation); this.oItemNavigation.destroy(); } };

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 191

1.1.3.17.6 Right-to-Left Support in Controls

Right-to-left support is defined as follows:

● Unicode defines the directionality of characters which the browser must take into account when arranging characters as words.

● The HTML "dir" attribute overrides the overall directionality of blocks (and influences the text alignment if not explicitly set). In detail there are many more effects, e.g. parentheses are mirrored and viewed as a "word" on their own, which changes their position.

● The HTML "lang" attribute does NOT influence text directionality.● document.dir can be used (browser support is there, it can be set in the bootstrap already, but webkit seems

to reset this to LTR, if set too early).● There is a <BDO> HTML tag which turns off the bidirectional algorithm, i.e. the character order is not reversed

if RTL and LTR words are mixed.● CSS 2.1 has also a "direction" property.

This means in a nutshell:

● Each character inherently belongs to a RTL or LTR script (defined by Unicode). Some characters like parentheses and dots have no inherent directionality. Browsers know all of this.

● For single "words" (characters sequences with same directionality) the browser knows the text direction, and does it "right" automatically, handling them as sort of blocks that get their internal text direction only from the used characters.

● These words/sequences/"runs" are separated by the direction-neutral characters like parentheses and dots - and obviously when character directionality changes.

● The direction in which these blocks are put next to each other depends on the base direction.● The default base direction of HTML is left-to-right, but can be inverted by setting the attribute "dir='rtl'", either

on the <html> tag or on any subregion which should have a different base direction.● This base direction also determines the default text alignment, the order of columns in tables and the

presentation of some direction-neutral characters: opening parentheses are still opening parentheses when RTL mode is switched! This means they render horizontally flipped.

● The algorithm for ordering words/runs/blocks according to the base direction only covers one level of mixed directionality. To achieve deeper nesting, spans with dir attribute can be used o define a subcontext with different base direction.

● While (as said above) words/runs internally always have the text direction implied by the used characters, this behavior can also be overridden (using the <bdo> tag or via CSS unicode-bidi:bidi-override) when the order of characters must follow the base direction regardless of the inherent character direction. E.g. because the characters do not form a word but are really just a list of characters, such as in a part number.

● The "lang" attribute defining the document language does not have any influence on directionality.

SAPUI5 Theming Concept - Right-to-Left Support

The UI development toolkit for HTML5 (SAPUI5) theming concept defines RTL support to be achieved as follows:

● All controls are styled for the LTR case in their "normal" CSS files● Images are put into/below the "img" subfolder

192 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● The CSS generator includes an RTL flipping algorithm (inherited from previous SAP UI technologies, proven over many years, similarly also used in the Open Source community, see CSSJanus):

○ border-left: is converted to border-right:, padding: 1px 2px 3px 4px; is converted to padding: 1px 4px 3px 2px;, float:left; is converted to float:right; etc. The assumption and experience is that this automated conversion does almost the whole job.

○ Most CSS properties, including CSS3 ones are supported● CSS generation also mirrors all images inside the "img" folder, as this has been found to be the right thing in

most casesSome images should not be mirrored for RTL. The RTL version of those images must then be put into the "img-RTL" folder with the same location and name. In this case the image reference in the CSS is modified to point to this image.

● A control should NOT write any special CSS classes to "notify" the CSS that RTL is turned onIn CSS the <HTML> tag's dir attribute can be checked to provide specific RTL style.

NoteThe written style is still mirrored in the actual RTL case.

Example:

html[dir=rtl] .sapUiBtn { color: red; }

However, this should only be required in rare cases. If you find yourself writing this kind of style more than 1-3% of the time, you should have another look at what SAPUI5's automatic CSS mirroring offers.

Programmatic Access to RTL

Some controls need to provide specific coding in case of RTL mode, e.g. because they are positioning or animating elements programmatically, not via CSS.

The SAPUI5 RTL configuration can be read by calling

var bRtl = sap.ui.getCore().getConfiguration().getRTL();

Impact on Applications

The text direction is LTR by default, but can be set using the various known configuration switches:

● URL parameter sap-ui-rtl=true● Configuration object: window["sap-ui-config"].rtl = true;● Script tag configuration: data-sap-ui-rtl="true"

SAPUI5 takes care of setting the overall page direction to "RTL". All UI5 content will then be displayed in RTL mode. For self-written controls and content you need to test. If manual style adoptions are required, you need to provide style specifically for the RTL case by using html[dir=rtl].

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 193

Steps

If SAPUI5 is configured to RTL mode, the core:

1. sets dir="rtl" on the HTML tag

○ The W3C officially recommends using the HTML attribute instead of the CSS properties, for example, directionality is a matter of content, not of presentation, and because the CSS properties may even be ignored.

○ Using the <HTML> tag (not the BODY tag) is recommended as well2. loads the respective library-RTL.css files

1.1.3.18 Synchronizing with the SAPUI5 Repository

The following sections describe how to use the SAPUI5 Repository and how to deploy the SAPUI5 application project on the ABAP Server. For this application type, the ABAP Server is used as a file share to serve browser requests. The SAPUI5 Repository is technically based on the BSP Repository of the ABAP Server.

Availability

The SAPUI5 repository is available in SAP Business Suite systems with version 7.00 or higher containing the User Interface Add-On for SAP NetWeaver, which contains the software component UI_INFRA. The team repository provider functionality, which is available in the Eclipse IDE, is available in SAP Business Suite systems with version 7.31 containing the User Interface Add-On, which contains the software components UI_INFRA and UI5_731.

The used SAPUI5 libraries are available in SAP Business Suite systems with version 7.00 or higher containing the NetWeaver UI Add-On in the software component UISAPUI5.

As of NetWeaver 7.40 SP1 all required SAPUI5 parts are already part of software component SAP_UI.

As an alternative for SAP Business Suite system of version 7.00 and higher you can use an interactive ABAP report offering similiar functionality. For more information, see the report documentation Using an Interactive ABAP Report to Synchronize [page 204].

Enabling Virus Scan During Upload

When uploading the files to the SAPUI repository, you can perform a virus scan.

As of SAP NetWeaver 7.00, SAP delivers the following virus scan profile for ABAP with the UI Add-On: /UI5/UI5_INFRA_APP/REP_DT_PUT.

This profile is used by the SAPUI5 repository API to store files in the SAPUI5 repository based on BSP repository. For example: Upload of a local file using SAPUI5 repository API /UI5/CL_REP_DT, method /UI5/IF_UI5_REP_DT~PUT_FILE from NetWeaver 7.00 on, or the SAPUI5 team repository provider in NetWeaver 7.31 or 7.40.

194 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The profile is deactivated when delivered. To activate it, create at least one basis profile. You can then activate one of the delivered profiles. By default, it links to a reference profile, which is the default profile.

Remarks

If you view the corresponding BSP pages on the ABAP server, they might look different to the version in Eclipse or at runtime:

● Trailing spaces in text lines are escaped with "!&nbsp;" in the respective BSP pages.● Lines longer than 254 are broken into several lines and have a + on position 255.

1.1.3.18.1 Using Eclipse to Synchronize

The following sections describe how to share, submit or retrieve a SAPUI5 application project with the SAPUI5 repository in Eclipse.

Setup

Several prerequisites have to be taken when using Eclipse to synchronize with the SAPUI5 repository.

● Make sure you install the SAPUI5 application development feature as well as the SAPUI5 ABAP repository team provider feature in you Eclipse installation.

● Make sure that the software component SAP UI5 TEAM PROVIDER ON 731 (UI5_731) is installed on the NetWeaver 7.31 ABAP backend

● Make sure that SAP Note 1684342 is applied in the NetWeaver 7.31 ABAP backend.

To use a SAPUI5 application as a Collaborative Human Interface Part (CHIP) in the page building service, you must register the application in the CHIP catalog on the server. Use report /UI2/CHIP/ for registration with the SAPUI5 Repository.

For more information, see the CHIP Administration section in the User Interface Add-On Administration Guide on the SAP Help Portal at http://help.sap.com/nw-uiaddon Application Help User Interface Add-On 1.0 SPS 04 for SAP NetWeaver SAP Library for User Interface Add-On for SAP NetWeaver User Interface Add-On Administration Guide .

Remarks

● Only CR+LF is supported as a new text file line delimiter.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 195

○ To set the new text file line delimiter in Eclipse, go to Window Preferences General Workspaceand change New text file line delimiter Other: to Windows.

○ To change the new text file line delimiter in Eclipse for an existing project, go to project ResourceProperties and change New text file line delimiter Other: to Windows.

○ To change the new text file line delimiter in Eclipse for an existing file, open the file and choose FileConvert Line Delimiters to Windows.

● Not all code pages (text file encoding) are supported.

○ To set the text file encoding for new files in Eclipse, choose Window Preferences GeneralWorkspace and change Text file encoding Other: to UTF-8.

○ To change the text file encoding in Eclipse for an existing project, go to project Resource Propertiesand change Text file encoding Other: to UTF-8.

○ To change the text file encoding in Eclipse for an existing file, go to file Resource Properties and change Text file encoding Other: to UTF-8.

Sharing the SAPUI5 Application Project with the SAPUI5 Repository

You want to upload a new SAPUI5 application into a new BSP application on the ABAP server.

Before the upload, make sure that

● You have created a SAPUI5 application using SAPUI5 application development tools, see Creating a SAPUI5 Application Project.

● Optional: You have tested the SAPUI5 application locally in Eclipse, see Testing SAPUI5 Applications in Eclipse.

● The ABAP system you are using is available in your SAP GUI Logon group. We recommend that you enable Single Sign-on.

Step 1: Creating a BSP Application (optional, not always required)

It is possible to create the BSP application with all required ICF nodes on the ABAP server remotely from Eclipse. However there might be cases in which this is not possible automatically:

● if the ABAP system is an SAP system (not a customer system) and the name of the BSP application and ICF node is in the customer namespace (for example, ZMYAPP)

● if the BSP application contains a namespace and that namespace has already been created in another system (for example, /ABC/MYAPP).

In these cases the BSP application has to be created manually with the following steps before sharing:

1. In the ABAP system, call transaction SE80. Go to the Repository Browser, and select BSP Application from the dropdown menu.

2. Create a BSP application and enter /UI5/CL_UI5_BSP_APPLICATION as the name of the application class.3. Save and activate the application.

196 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

4. Next, call transaction SICF, where you create a SAPUI5 application-specific ICF node.

a. In the Service Path field, select /sap/bc/ui5_ui5/sap as the path (or alternatively the respective customer namespace /sap/bc/ui5_ui5/<namespace), and choose Execute.

b. In the context menu for the sap (or the respective customer namespace) node, choose New Sub-Element.c. In the Create a Service Element dialog, use the same name as for the BSP application you created as the

Name of Service Element to Be Created and choose Enter.d. Provide a description text for the ICF node and choose Save.e. Return to the tree and position the cursor on the new service node.f. Right-click the new service node to call the context menu, and choose Activate Service, then Yes.

Step 2: Sharing the SAPUI5 Application with the SAPUI5 repository

The SAPUI5 application project can be shared with the SAPUI5 Repository as follows:

1. In Eclipse, go to the Project Explorer view and select the required SAPUI5 application project.

2. In the context menu of the selected SAPUI5 application project, choose Team Share Project… .

3. Select SAPUI5 ABAP Repository as the repository type.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 197

4. Choose Next. Configure the connection to the ABAP system by using the Browse… button. You can only select system connections that are configured in the SAP GUI Launchpad.

5. Choose Next. Provide the required information for client, user, password, and language.

NoteChoosing the correct logon language is important. When creating a new repository this will become the original language of the repository. For submitting files to the repository you have to be logged on in the original language, otherwise an error will occur.

198 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

6. Choose Next. The SAPUI5 application project can either be shared with an existing or with a newly created BSP application.

a. Select Create a New BSP Application and enter name, description, and package (manually or via the Browse… button).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 199

b. Alternatively, if the BSP application has been created manually, or if you want to download an existing one, choose Select a BSP Application and select an existing BDSP application artifact for SAPUI5 from the list.

200 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

7. Choose Next.

NoteIf the new BSP application belongs to a transportable ABAP package, choose/create a transport request before finishing the wizard. Since transport requests are not automatically released, explicitly release them later using transaction SE61.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 201

8. Choose Finish.

The selected SAPUI5 application project is now connected to the SAPUI5 BSP application artifact of the SAPUI5 Repository. A description containing the ABAP system, client, user, language, and SAPUI5 BSP application name is displayed next to the project name.

Submitting the SAPUI5 Application Project to the SAPUI5 Repository

Before submitting, make sure that

● You have created a SAPUI5 application, see Creating a SAPUI5 Application Project.● You have shared your SAPUI5 application project, see Sharing the SAPUI5 Application Project With the

SAPUI5 Repository.

To submit the SAPUI5 application project to the SAPUI5 repository, proceed as follows:

1. In Eclipse, choose Team Submit in the context menu of the selected SAPUI5 application project. If a logon is required, enter your password in the logon popup and choose OK.

202 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

If you submit changes of a SAPUI5 application project, the SAPUI5 runtime library version of the server is compared against the versions which have been installed in Eclipse. A warning is shown, if they do not match, see SAPUI5 Runtime Libraries Server Version Check.

2. Select all files. You get a list of files that have been modified (added, updated, or deleted) in the client. The dialog shows the files for which submit conflicts exist, for example, if another user has submitted a newer file version in the meantime. Submit conflicts must be resolved before submission. If a file is already locked in a transport request, the corresponding request is shown in the dialog. If the SAPUI5 BSP application belongs to a transportable ABAP package, you have to choose a transport request. Note that transport requests are not automatically released when the files are submitted; you still have to release them using transaction SE09 in the underlying ABAP system.

3. Choose Finish.

All files have been submitted to the SAPUI5 Repository and are available under the corresponding SAPUI5 BSP application. The SAPUI5 application project can now be run from a Web browser calling the underlying ABAP system. You have the convenient option in the context menu for an HTML page of starting a browser with the correct URL from the BSP application displayed in the ABAP Workbench (SE80).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 203

Retrieving the SAPUI5 Application Project from the SAPUI5 Repository

Before retrieving the SAPUI5 application project from the SAPUI5 repository, make sure that

● You have created a SAPUI5 application, see Creating a SAPUI5 Application Project.● You have shared and submitted the SAPUI5 application, see Sharing the SAPUI5 Application Project and

Submitting the SAPUI5 Application Project.● The ABAP system you are using needs to be available in your SAP GUI Logon group.

To retrieve the SAPUI5 application project from the SAPUI5 repository, proceed as follows:

1. Create a generic project in Eclipse: Choose New Project General Project . Enter the same name that is used for the SAPUI5 BSP application artifact in the ABAP system. Choose Finish.

2. Share the SAPUI5 application project with Team Provider by choosing the existing BSP application, see Sharing the SAPUI5 Application Project with the SAPUI5 Repository [page 196].

3. Synchronize the SAPUI5 application project as follows: In the context menu of the selected project, choose Team Retrieve . Next, choose Select All to select the conflicting files as well.

4. Choose Finish.

Application-project-related files have been retrieved from the SAPUI5 Repository.

The SAPUI5 application project can now run locally in Eclipse, see Testing SAPUI5 Applications in Eclipse.

1.1.3.18.2 Using an Interactive ABAP Report to Synchronize

You can either upload a SAPUI5 application to or download a SAPUI5 application from the SAPUI5 repository by using an interactive ABAP report.

Uploading or Downloading a single SAPUI5 Application

Prerequisites

You have installed SAP NetWeaver UI Add-On Version 1.0 or SAP NetWeaver 7.40 including the UI Add-On.

● To upload or download a single SAPUI5 application, use /UI5/UI5_REPOSITORY_LOAD. When running the report, enter the name of the SAPUI5 application in the respective input field on the screen.

204 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Compared to the ABAP team repository provider it does not offer a built-in code merge. Here, a separate source code repository like git or Subversion (SVN) may be used. The report is shipped via SAP note 1793771

Up/Download SAPUI5 Application into/from UI5 Repository and as part of NetWeaver UI Add-On SP03 delivery.

Uploading one or more SAPUI5 Applications from an Archive

Prerequisites

You have installed User Interface Add-On Version 1.0 SP06 or SAP NetWeaver 7.40 SP05.

● To upload a SAPUI5 application from a zip or war archive, use /UI5/UI5_REPOSITORY_LOAD_HTTP.● To upload several SAPUI5 applications from a zip or war archive at once, use /UI5/

UI5_REPOSITORY_LOAD_HTTPN.

To execute the report, you need to provide several parameters, as displayed in the following screenshot.

You can either enter the parameters in the displayed input fields or you provide them in an optional file .Ui5RepositoryUploadParameters located in the archive. Each line represents a parameter. The format is <parameter name> = <parameter value>.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 205

The report can be run in several modes:

● Delta Mode: Mark this checkbox in case you only want to upload those files, that are new or that have been modified.

● Test Mode: Mark this checkbox in case you want to see a log file displaying what the report is doing.

Additionally, both reports and the function module /UI5/UI5_REPOSITORY_LOAD_HTTP have the following features:

● They can automatically convert text files from unix format to windows-like format.● You can schedule them on the SAP Web Application Server.● The possibility to automate Maven builds as a remote-enabled function module is available.

For more information, see the report documentation as well as the documentation of the function module /UI5/UI5_REPOSITORY_LOAD_HTTP in the system and SAP note 1893133 .

1.1.3.18.3 Handling Conflicts

Submit/Retrieve Dialogs

When you submit or retrieve a change, the Conflict column on the Submit Changes or Retrieve Changes screen indicates whether there is a conflict for a file. The dialog shows the files for which submit/retrieve conflicts exist, that is, another user has submitted a newer file version in the meantime. Submit conflicts must be resolved before submission. If retrieve conflicts cannot be solved, the local files are overwritten.

To set the conflict files as resolved, select the file (or multiple files) and choose Set Resolved. The same functionality is also available in the context menu of the selected file or files.

To display the conflicts with the Compare Editor, choose Edit Conflict. The Edit Conflict function is not supported for multiple file selection.

Once you have analyzed and edited the changes, you can choose Save and Set as Resolved for the conflict file.

206 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Synchronize View

In the Synchronize view, you can compare the local and remote state.

1. Mark the SAPUI5 application project in the Project Explorer in Eclipse.

2. To open the Synchronize view, and choose Window Show View Others ... , then choose TeamSynchronize .

a. To connect to a synchronization type, choose the Synchronize … icon, select Synchronize with SAPUI5 Repository as synchronization type, and choose Finish.

b. To update the Synchronize view, press F5 in the Synchronize view.3. The Synchronize view now shows differences between the local and remote state for all shared projects, by

indicating whether the project is in sync with the repository or, if not, indicating the differences.

The Synchronize view also allows you to schedule a periodic refresh of the state of the files in the backend.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 207

Compare Editor

1. From the Synchronize view, you open the Compare Editor by right-clicking the conflicting file and choosing Open in Compare Editor (or double-clicking the file).

2. You can now display and resolve the conflicts in the Compare Editor.3. Once the conflict is resolved, you can set the status of the file to "Resolved" by right-clicking the file and

choosing Set Resolved. The file is now ready to be submitted.

208 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.18.4 Testing the SAPUI5 Application on an ABAP Server

To test a SAPUI5 application that you have uploaded to an ABAP system, you can directly launch its public URL in a browser window.

Prerequisites

● You have shared a SAPUI5 application via the SAPUI5 ABAP repository team provider with the ABAP system.● You have synchronized the application with the ABAP system.

You have the following options to launch a synchronized file, for example the index.html, on the ABAP server:

● Right click the file in the Project Explorer and choose Run As Run On ABAP Server .

● Open the file in an editor and from the Eclipse and choose Run As Run On ABAP Server .

The launch option is only available if the file is accessible via URL, for example, if it is in the WebContent folder.

The URL of the selected file is opened in a browser window. The URL has the following pattern:

<protocol>://<host name>:<port number>/sap/bc/ui5_ui5/<namespace>/<application name>/index.html?sap-client=<client>&sap-ui-language=<language>&sap-ui-appcache=false

NoteThis URL contains test parameters. Do not use them for productive use.

You can also start the SAPUI5 application as follows:

Select the SAPUI5 application-specific Internet Communication Framework (ICF) node in transaction SICF under sap/bc/ui5_ui5/<namespace>/<application name>, and choose Test Service from the context menu. This starts your index.html page automatically.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 209

Cache Behavior for Application Resources

By default, the application files are stored in the browser cache for one year to speed up the performance in a productive environment. To get the latest changes you need to force your SAPUI5 start page to refresh, for example with CTRL + F5 on Windows systems. If the refresh does not work, clear your browser cache.

The following is an experimental feature which might change in future versions of SAPUI5: If you are in development mode and like to immediately get the latest changes without refreshing your SAPUI5 start page, you can add the experimental URL parameter sap-ui-xx-devmode to the SAPUI5 start page in order to force the browser to check whether there is a newer version of the application files available. When switching between development and productive modes, refresh the SAPUI5 start page. If the refresh does not help, clear your browser cache.

Using the Application Cache Buster

If you activate the application cache buster in the start page of the application in which the SAPUI5 bootstrap is located by setting data-sap-ui-appCacheBuster="true", the SAPUI5 application runtime handler on ABAP side supports the application cache buster, see Application Cache Buster. In this case, the ICM server cache on ABAP side as well as the browser cache is used and the application cache buster mechanism ensures that all those resources which are supported by the application cache buster mechanism are up to date.

Technical Information

● Under typical conditions, for example, when using SAPUI5 applications or when doing development with the SAPUI5 ABAP repository team provider or the SAPUI5 repository load report, the application cache buster works fully automatically.

● As of UI AddOn 1.0 SP03 it may be necessary after system- and language imports for a SAPUI5 application into the SAP NetWeaver Web AS to reset its internal cache buster information. You may explicitly use or schedule the ABAP report /UI5/RESET_CACHEBUSTER to do so on all servers. As an alternative you can trigger the reset for a specific SAPUI5 application from the browser using the URL "<application base path>/resetcachebuster".

● The internal cache buster information for a SAPUI5 application becomes outdated every two hours and is then calculated automatically. As a consequence, the underlying server side cookies 'cachebuster_info' get recalculated without the need of manual acitivity.

1.1.3.18.5 Creating Alias for ICF Node with SAP Corbu Logon Screen

To create an alias for the ui5_ui5 ICF node with an SAP Corbu logon screen (available with version 7.31 and higher), proceed as follows:

210 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1. In the ABAP Suite system, call transaction SICF and choose Execute (F8).2. Choose External Aliases (Shift+F6)3. Select the host, for example default_host, and choose Create New External Alias (F5).4. Enter a name in the External Alias field. The name must start with a slash, for example /ui5.5. On the Trg Element tab, double-click the target handler /default_host/sap/bc/ui5_ui5 .6. On the Error Page tab, select the Logon Errors tab, then System Logon, and choose Configuration.7. In the System Logon Configuration dialog, choose Define Service-Specific Settings.8. Under Select Display, select the fields that are to be displayed on the logon screen; these are generally

System ID, Client, and Language.9. Under Logon Layout and Procedure and SAP Implementation, select Signature Design for Screen and SAP

Corbu for Theme.10. If you choose Adjust Links and Images, you have the option under Adjustment of the Logon Page to specify the

URLs for the images you want to use instead of the standard images.11. Choose Input (Enter) to confirm the selection.12. Choose Save (Ctrl+S) to save the new alias.

For information on the ICF, see:

● System Logon in the NetWeaver 7.0 EHP 3 application help on the Help Portal under System Logon● Administration of Server Functions in the NetWeaver 7.0 EHP 3 application help on the Help Portal under

Administration of Server Functions

1.1.3.18.6 Using the ABAP Communication Log for Troubleshooting

For troubleshooting purposes, you can use the ABAP Communication Log to log all REST requests from and to the ABAP system.

Proceed as follows:

1. To open the ABAP Communication Log view in Eclipse, choose Window Show View Others... and then choose ABAP ABAP Communication Log .

2. To start the logging, choose Start logging. You can stop the logging by choosing Stop logging.3. The ABAP Communication Log displays all requests between Eclipse and the connected ABAP system, giving

you information about the HTTP method (GET, PUT, POST, DELETE), the query parameters of the request, and the HTTP status code.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 211

4. If you click a request in the list, the details of this request are displayed (such as Request, Response, Stack Trace), giving you information about the HTTP header fields and the content of the request and the response.

.

1.1.3.18.7 SAPUI5 Runtime Libraries Server Version Check

When you develop SAPUI5 applications with SAPUI5 application development tools, the code completion and application preview features are based on SAPUI5 runtime libraries installed in your Eclipse. However, after you

212 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

have deployed the application to the ABAP server and execute it there, it will use the SAPUI5 runtime libraries installed on the ABAP server.

We therefore recommended that you always have the same library version installed in Eclipse and on the ABAP server. If this is not the case, for example, if the local version is higher than the one on the server, the following could happen:

● You may use features during development that are not yet available on the server.● When you test your application in Eclipse, the application may behave differently, for example, because in the

newer runtime version some issues are fixed which still occur on the server.

We recommend to check the compatibility rules which apply to SAPUI5 runtime libraries, see Compatibility Rules.

When you share a SAPUI5 application project with the SAPUI5 ABAP Repository, or start the Submit wizard, a version comparison of the local libraries against the server is performed. If the versions differ, a warning message is shown which shows the current versions. If you want to proceed anyways, you can suppress the popup for that project and this version constellation.

To prevent this, we recommend the following measures:

● Check the JavaScript documentation of the used controls and their methods for @since tags. They indicate which version has introduced a new feature which you are going to use.

● When testing in Eclipse you should configure it to use the runtime libraries located on the server instead of the local ones, see SAPUI5 Library Location Used for Testing.

● Always test your application on the server after submitting changes.

1.1.3.18.8 Translation Guide for SAPUI5 Application Developers

Texts in SAPUI5 applications can be translated in an ABAP system. It is a requirement that the name of the file containing the text elements ends with '.properties' and a special key in the format # SAPUI5 TRANSLATION-KEY <GUID with 32 characters must be provided in the first line. In addition, every text element needs a classification such as the text type.

Before you translate texts, make sure that you are using the SAPUI5 repository to store your UI5 application artifacts, see Synchronizing with the SAPUI5 Repository.

Functional Overview

● The purpose of the text API in the SAPUI5 repository is to enable an ABAP translation process for text elements of SAPUI5 applications developed in Eclipse that are stored in the SAPUI5 repository.

● The text elements are included in a property file (here denoted as a '<name>.properties' file, where '<name>' stands for an identifier).

● The text elements stored in '<name>.properties' files are transferred to an ABAP server.● In addition, these table entries are written to a transport request.● These texts can then be translated in the usual way.● The master language of the SAPUI5 repository is taken as the master language for the submitted text

elements.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 213

● The translated texts can then be accessed during runtime.

Prerequisites for Translating Text Elements

The '<name>.properties' file must fulfill certain prerequisites for processing:

The table entries for the text elements are written if the following prerequisites are met:

● The file name must end with '.properties'.● The first line in the '<name>.properties' file must contain a certain identifier: # SAPUI5 TRANSLATION-KEY

<GUID with 32 characters>.

CautionThis GUID will serve as a unique identifier for the 'properties' file, therefore it must never be copied to other '<name>.properties' files and it must never be changed in this file. The GUID can be created with the ABAP function module 'GUID_CREATE', or the complete line can be generated with the ABAP report /UI5/TEXT_FILE_GEN_TRANS_KEY. Since this GUID is the only unique identifier, it is possible to relocate or rename the properties file and the text elements in the table will be preserved.

● The file must not contain any duplicate text elements.

Additionally, transport entries are created in the target ABAP system if:

● The corresponding SAPUI5 BSP application is not located in a local package ($TMP).● A valid transport request is already available.

Whenever the property file is relocated, whether to another folder, application, or package, the file must be submitted again to the SAPUI5 repository.

If the BSP application on the ABAP server is reassigned from a local ($TMP) to a non-local package, the file also needs to be resubmitted. All text elements will be generated again with the new creation timestamp.

NoteAs the master language of the SAPUI5 repository serves as the master language of the texts, it is important that the same language is used for the creation of the repository as has previously been used for the property files.

When using the SAPUI5 repository team provider and creating the BSP application manually the correct language has to be chosen on the logon screen.

Classification of Text Elements

Text elements in the '<name>.properties' file are simple value key pairs separated by an equals sign. However, in order to enable proper translation for these text elements, it is necessary to classify the text elements with additional information. This additional information must be placed in the line directly above the text element and must begin with the number sign ('#').

214 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The complete line must have one of the following structures:

● #<TextType>● #<TextType>,<MaximumLength>● #<TextType>,<MaximumLength>:<AdditionalContextInformation>● #<TextType>:<AdditionalContextInformation>

Attributes of Text Elements

Text Type

Each text element must have a text type assignment. Text types can be, for example, XBUT for button texts, XFLD for field labels, or XTXT for general texts. A list of the various possible text types is provided below.

Maximum Field Length

The optional maximum text length information can be provided directly after the text type, separated by a comma.

Additional Context Information

An optional additional comment is provided for the translator, separated by a colon.

List of Text Types

SAPUI5 short texts:

Text Type Corresponding S2X Type Description

XACT accessibility Accessibility

XALT alternativetext Alternative text

XBCB breadcrumbstep Breadcrumb step

XBLI listitem Bullet list item text

XBUT button Button text

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 215

Text Type Corresponding S2X Type Description

XCAP caption Caption

XCEL cell Cell

XCKL checkbox Checkbox

XCOL tableColumnHeading Column header

XCRD tabStrip Tabstrip

XDAT datanavigationtext Data navigation text

XFLD label Label

XFRM frame Frame

XGLS term Term

XGRP grouptitle Group title

XHED heading Heading

XLGD legendtext Legend text

XLNK hyperlink Hyperlink

XLOG logentry Log entry

XLST listbox List box item

XMEN menu Menu header

XMIT menuitem Menu item

XMSG messagetext Message text

XRBL radio Radio button

XRMP roadMapStep Roadmap step

XROW tableRowHeading Table row heading

XSEL selectionText Selection text

XTBS tab Tabstrip text

XTIT tableTitle Table title

XTND treeNode Tree node text

XTOL quickInfo Quick info text

XTXT generaltext General text

SAPUI5 long texts with length of more than 120 characters:

NoteThe total line length of SAPUI5 long texts must not exceed 255 characters.

Text type Corresponding S2X type Description

YACT accessibilitylong Accessibility (long)

YBLI list Bullet list item text

216 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Text type Corresponding S2X type Description

YDEF definition Definition

YDES description Description

YEXP explanation Explanation

YFAA faqa FAQ answer

YFAQ faq FAQ

YGLS glossarydefinition Glossary definition

YINF instruction Instruction

YLOG logEntrylong Log entry

YMSE errorMessage Error message

YMSG messagetextlong Message text (long)

YMSI informationMessage Information message (long)

YMSW warningMessage Warning message

YTEC technicaltextlong Technical text

YTIC ticker Ticker / marquee

YTXT generaltextlong General text (long)

NOTR No translation

Example: <name>.properties File

NoteExchange the <GUID> in the first line with a real generated 32-character GUID.

# SAPUI5 TRANSLATION-KEY <GUID>

#XBUT,20

BUTTON_SAVE = Save

#XMSG

MESSAGE_ERROR1 = Error during creation of {0}

#XCAP,20: furniture element

CAPTION_TABLE1 = Table 1

#XFLD: first name in address input dialog

FORMULA_FIRSTNAME = First Name

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 217

Information for Translators

The following information is relevant for translators:

● SAP Note 1686090 must be implemented in the translation system to enable the translation of SAPUI5 text elements. SAPUI5 text elements are treated as ABAP short texts with translation object type: UI5T.

● The translation object name is a GUID, which is the key taken from the original property file containing the text elements (the GUID from the first line) (see under Prerequisites: # SAPUI5 TRANSLATION-KEY <GUID with 32 characters>).

● The text key of each text element consists of the text type and an individual GUID, separated by a space.● The UI5T texts are stored in the following database tables which are stored with a SAP/customer namespace:

○ /UI5/TREP_TEXT: Master table with the text name, unique text GUID, text type, additional context information, and another GUID that is the translation object name (the GUID from the property file).

○ /UI5/TREP_TEXT_T: Language-dependent table containing the original and translated text; the key is the text GUID as in table /UI5/TREP_TEXT and the language key.

○ /UI5/TREP_FILES contains the (translation) object name (the GUID from the property file) and path information for the property file.

Finding the Where-Used Location of a Text Element

Finding the origin of a text in the source code has to be done manually:

● Use GUID to find the corresponding property file (path information) in table /UI5/TREP_FILES; the GUID corresponds to the field PROP_FILE_GUID.

● The translator sees a key for each text element, which is a concatenation of the text type and another GUID. This GUID corresponds to the field PROP_TEXT_GUID in table /UI5/TREP_TEXT; here you can find the text name for a particular GUID.

● The developer can use this text name to search in the corresponding project in Eclipse to find the location where this particular text is used.

1.1.3.19 Building Mobile Applications with SAPUI5

Related Information

Best Practice for Building Mobile Applications [page 219]These best practice provides recommendations how to achieve a clear structure and architecture for SAPUI5 applications.

Using MVC in Mobile Apps [page 228]

Handling Navigation and Lifecycle Events [page 235]

218 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Mobile apps are often composed of several pages and the user can drill-down to detail pages and go back up again. This is often visualized by horizontal slide animations. SAPUI5 supports this pattern by providing the sap.m.App and sap.m.NavContainer controls, which handles the navigation between the pages.

Adapting to Platform and Form Factors [page 238]The SAPUI5 Mobile library target devices run different operating systems and have very different screen sizes and pixel densities. SAPUI5 does some adaptations automatically. In addition to that, the application can further adapt to the current device.

Working with Lists [page 250]

Triggering Phone, SMS and E-Mail [page 257]With SAPUI5 for Mobile you can easily trigger native mobile phone applications such as e-mail, telephone, and text messages.

Scrolling in SAPUI5 Mobile [page 259]

Running SAPUI5 Mobile Apps in Hybrid Web Containers [page 262]

Using Images in Mobile Applications [page 264]

Message Handling [page 268]

Navigation Using Browser History [page 271]

Mobile Events [page 273]

Styling and Theming Mobile Controls [page 276]

Building Charts with MAKit [page 276]

1.1.3.19.1 Best Practice for Building Mobile Applications

These best practice provides recommendations how to achieve a clear structure and architecture for SAPUI5 applications.

NoteThe concepts described in the following sections are applied to the Shopping Cart demo app, see Shopping

Cart . You can use its source code to understand the concepts described in the best practice.

Caveats

Technically, you can code the whole application in one single HTML file. The simple "Hello World" application is built like this to make the basic functionality easy to understand. But when you create more complex applications, a clear architecture is the key for efficient development and maintainability.

If several possible options exist, for example with regard to the file structure, the granularity of views, or the use of the MVC concept, and the Best Practices use a specific option, this does not mean that the other options are wrong. In fact, other options may suit specific applications even better and some decisions may depend on project experience or team setup.

Nevertheless, this document intends to provide valuable suggestions for a good application structure. Keep in mind, though, that it does not represent the only possible or correct way to build SAPUI5 applications.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 219

The Best Practices contains sections that refer to concepts or controls which are only available in the sap.m mobile library, but most suggestions also apply to desktop applications, or are at least similar for desktop applications.

Overview

The figure below shows the components and dependencies based on the Shopping Cart demo application. The Shopping Cart demo application is a SAPUI5 Mobile application consisting of six pages. The pages are created by using one view and a controller each.

The pages are complemented by an application view and a controller for handling the navigation between views, including the handling of back/forward buttons in the browser. The view content construction in the views and the functionality, navigation, and eventing in the controllers are separated.

For loosely-coupled communication the EventBus is used. There are no direct dependencies between the views, and the EventBus events are only used for navigation and parameter handover between pages.

Two data models exist:

● "Product", containing the available goods● "Cart", containing the items put into the shopping cart

In addition to these two models, two additional models contain the resources used by the application: one for images and one for translated texts, see Localization and Image Model.

The application is launched from within Application.js (the “App Bootstrap”), which creates the data models and the root/app view. The Formatter utility class is used, but the example does not contain custom controls.

The index.html page itself only contains minimal code for configuring locations and loading the Application.js, see index.html.

As the architecture of an application depends on the size, nature, and structure of the respective application, the example will not fit all applications, but should at least give a rough idea.

220 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

File Structure

The following assumptions are made with regard to the file structure:

● As no resource folder is used, the SAPUI5 core/libs can be stored anywhere, that is in a local resource folder or somewhere else.

● As the app is not reused in other apps, it is not necessary to model namespaces in the views/controller paths.

The suggested application structure looks as follows:

The <webapp_root_folder> contains the following namespaces:

● Application.js● css folder: Contains all CSS files and the related images, that is style.css and more stylesheets, if required● ext folder: Contains all reused third party java script● i18n folder: Contains all property files for localization, for example:

○ i18n.properties○ i18n_de.properties○ i18n_en.properties

● model folder● util folder: Contains all helper classes● view folder: Contains all view and controller files go here; all file names shall start with an upper case letter● img folder: Contains all image files (png, jpg, gif, …)● <someNamespace>: Contains all on-the-fly controls defined in the application, for example,

<controlName>.js

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 221

● index.html

Depending on the application, not all resources may be required.

“someNamespace” is, for example, salesorders or a nested namespace, for example sap/hcm/hiring. This namespace is reflected in the package names of the controls, for example var btn = new salesorders.MyButton(); or new sap.hcm.hiring.CustomButton();.

You can use these namespaces also for views, controllers and helper classes, but this depends on the application. The localResources or registerModulePath statements need to be adapted accordingly, see index.html.

index.html

The index.html entry page for an application should have the following structure and content:

● HTML5 DOCTYPE● Meta tag instructing Internet Explorer (IE) to use the newest rendering mode; for SAPUI5 Mobile this is done

in preparation for future IE support, for SAPUI5 desktop application this information is required to make sure IE does not use a compatibility mode

● Charset settings; usually UTF-8, but may need to be adapted to the actual charset● Application <title>● SAPUI5 bootstrap script tag for loading SAPUI5 and the required control libraries and theme● Any application CSS stylesheet links; the SAPUI5 theme stylesheets are inserted directly after the bootstrap

tag, so loading the application stylesheets here guarantees that they can more easily override SAPUI5 styles● Script tag starting the application● HTML body where the SAPUI5 content will be rendered

Of course, specific applications may require additional script tags to load external files or some HTML structure within the body or a script tag before loading UI5 to configure the UI5 runtime. This suggestion here does not say such extensions are not allowed.

Example index.html file

<!DOCTYPE html><html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta charset="UTF-8">

<title>XYZ</title>

<script id="sap-ui-bootstrap" src="XYZ" data-sap-ui-theme="XYZ" data-sap-ui-libs="XYZ"> </script>

<link rel="stylesheet" type="text/css" href="css/style.css">

<script> // Tell UI5 where to find application content sap.ui.localResources("util"); // paths starting with "util" will be resolved relative to the index.html location sap.ui.localResources("view"); jQuery.sap.registerModulePath('ApplicationBase', 'ApplicationBase'); // this file will be loaded directly from the same directory

222 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

jQuery.sap.registerModulePath('Application', 'Application');

// Launch application jQuery.sap.require("Application"); var oApp = new Application({root : "content"}); // instantiate your application and mark the HTML element with id "content" as location for the UI </script>

</head> <body class="sapUiBody" id="content"> </body></html>

Application.js

The first code to be executed at runtime is the Application.js. The init function is executed right away and triggers tasks that can be executed without having the DOM available, for example loading JSON files from the server. The main function is only called after the DOM is ready. This is the point in time when you instantiate the app view and controller and place the view in the DOM.

Example for Application.js

jQuery.sap.declare("Application");jQuery.sap.require("ApplicationBase");

ApplicationBase.extend("Application", {

init : function() { // set global models var model = new sap.ui.model.json.JSONModel("model/data.json"); var imgModel = new sap.ui.model.json.JSONModel("model/img.json"); sap.ui.getCore().setModel(model); sap.ui.getCore().setModel(imgModel, "img"); }, main : function() { // create app view and put to html root element var root = this.getRoot(); sap.ui.jsview("app", "view.App").placeAt(root); }});

Navigation Handling and Events

This section is intended for SAPUI5 Mobile, in particular for applications using the sap.m.App or sap.m.NavContainer control which handles navigation between pages. However, it can also be used for SAPUI5 applications where views trigger a parent to display different views.

We recommend to use the SAPUI5 EventBus to inform other views about navigation requests.

The following naming shall be applied:

● Channel name: "nav"

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 223

● Event name for forward navigation to another page: "to"● Event name for backward navigation to the previous page: "back"

// navigate to another pagevar bus = sap.ui.getCore().getEventBus();bus.publish("nav", "to", { id : "Product"});

// navigate to the previous pagevar bus = sap.ui.getCore().getEventBus();bus.publish("nav", "back");

When navigating to another page you often need to pass some information to the target page. This information shall be put to the data of the event. The navTo function of the app controller then passes the data to the app control. It can then be accessed in the onBeforeShow event, which is called on the pages of the app control, that is, the view containing the page.

Navigation to another page:

var bus = sap.ui.getCore().getEventBus();bus.publish("nav", "to", { id : "Product", data : { context : evt.getSource().getBindingContext() }});

Receiving the onBeforeShow event in the target view:

sap.ui.jsview("view.Product", { ... onBeforeShow : function(evt) { this.getController().onBeforeShow(evt); }, ...

Handling the event in the target's view controller

sap.ui.controller("view.Product", { ... onBeforeShow : function(evt) { if (evt.data.context) { this.getView().setBindingContext(evt.data.context); } }, ...

History Handling

History handling is one of the most difficult topics in implementing a mobile application. Android and Blackberry devices have a physical back button which triggers for both web and hybrid apps a back navigation in the browser history

224 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteRunning Demo

The Navigation app illustrates the usage of the jQuery.sap.history for integrating the Android back button into application navigation.

To launch it, see Navigation

In the architecture example in this Best Practices, the code for history handling is contained in the app controller, including the subscription to history changes:

sap.ui.controller("view.App", { onInit : function() { // init history mgmt jQuery.sap.require("jquery.sap.history"); jQuery.sap.history({ routes: [{ path : "page", handler : jQuery.proxy(this.historyPageHandler, this) }], defaultHandler: jQuery.proxy(this.historyDefaultHandler, this) }); ...

The app controller sets the history for forward navigation:

sap.ui.controller("view.App", { ... navTo : function(id, writeHistory, navType, data) { ... // write history if (writeHistory === undefined || writeHistory) { jQuery.sap.history.addHistory("page", {id: id}, false);}

On opening a dialog, a virtual history has to be added. This is not handled in the app controller, but in the related view or controller:

jQuery.sap.history.addVirtualHistory();sap.m.MessageToast.show("Product added to your shopping cart");

Instance Manager

When you open dialogs and popovers, they automatically register themselves in the instance manager. This allows you to easily check for open dialogs or popovers when navigating back, and to close them without maintaining references yourself. The following code shows the navTo function of the app controller:

navTo : function(id, writeHistory, navType, data) { ... // navigate on app var app = this.getView().app; if (navType === jQuery.sap.history.NavType.Back) { if (sap.m.InstanceManager.hasOpenDialog()) { sap.m.InstanceManager.closeAllDialogs(); } else {

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 225

app.backToPage(id); } } ...

Localization

We recommend to use data binding and the sap.ui.model.resource.ResourceModel as a named model for localization. This facilitates the use of translation keys instead of actual texts.

You can also use ResourceBundles, but they require code execution for every translated text set to a control.

For more information, see Use of Localized Texts in Applications.

The following guidelines apply:

● Use i18n as model name● Use only one global property file that contains all texts used in the views.● Group view-specific texts with a prefix; to avoid redundancies, do not apply a prefix to texts which are reused

across view boundaries

Example:

var oModel = new sap.ui.model.resource.ResourceModel({bundleName:"i18n", bundleLocale:"en"});

// set the resource model as global model with the name "i18n" sap.ui.getCore().setModel(oModel, "i18n");

var oControl = new sap.ui.commons.Button({ text : "{i18n>MY_BUTTON_TEXT}"});

Image Model

When referencing images in an application it is more convenient to collect all access paths in one central place instead of having them everywhere in the code. To achieve this, you store them in a JSON file, make this file available with a global JSON model named "img", and bind the controls against this model.

The following code snippet shows how image access paths are stored in a JSON file:

{ "icon" : { "ui5" : "img/SAPUI5Icon.png", "cart" : "img/cart_TabButtonItem.png" }}

The following code snippet shows how images are made available with a global JSON model:

ApplicationBase.extend("Application", { init : function() {

226 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

var imgModel = new sap.ui.model.json.JSONModel("model/img.json"); sap.ui.getCore().setModel(imgModel, "img"); ...

The following code snippets show how the controls are bound against img model:

this.page = new sap.m.Page({ title : "Shopping Cart", icon : "{img>/icon/ui5}", ...

This approach even allows to switch all images to a different set at runtime with one line of code, for example, to provide differently colored image sets for different SAPUI5 themes.

Utilities

When developing an application, you need to reuse JavaScript coding in multiple views and controllers. You can reuse code by putting the code into separate files which are stored in the util folder. To dynamically load this code at runtime, the SAPUI5 modularization concept is used, see Modularization and Dependency Management.

An example for this is the reuse of a formatter in multiple data bindings. The formatter code is defined in util/Formatter.js as follows:

jQuery.sap.declare("util.Formatter");

util.Formatter = { price : function(value) { jQuery.sap.require("sap.ui.core.format.NumberFormat"); var numberFormat = sap.ui.core.format.NumberFormat.getFloatInstance({ maxFractionDigits: 2, groupingEnabled: true, groupingSeparator: ".", decimalSeparator: "," }); return numberFormat.format(value) + "\u20AC"; } };}

This is a view using the formatter in a data binding:

jQuery.sap.require("util.Formatter");

sap.ui.jsview("view.Home", {

createContent : function(oCon) { ... this.productList = new sap.m.List({}); this.productList.bindAggregation("items", { path : "/products", template : new sap.m.StandardListItem({ title : "{name}", info : { path : "price", formatter : util.Formatter.price } }) ...

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 227

1.1.3.19.2 Using MVC in Mobile Apps

For SAPUI5 mobile applications, you can use the same Model View Controller concept as for desktop apps, see Model View Controller (MVC) Approach.

You can choose the granularity of views freely, for example, one view per page. The following sections illustrate the use of the MVC concept in mobile applications to decouple the different application parts. The following sections are not intended as a best practice document, but rather to illustrate the interaction of views.

For a more complex example, see Best Practice for Building Mobile Applications.

An MVC Demo Application

To illustrate the MVC use, we build a simple Mobile application consisting of two pages.

NoteRunning Demo

To launch and inspect the MVC demo app, see Model View Controller

The following three views are used:

● One XML view for the app control which forms the root level of the application● One XML view for the home page● One JSView for the detail page

The home page displays a list of countries. By tapping any of the countries, you navigate to the detail page with more information about the selected country.

NoteThe app control holds its child controls in the pages aggregation. This does not mean that only sap.m.Page controls can be aggregated: The demo application puts the views into the aggregation. Therefore, calling app.getPages() returns the directly aggregated views and not an sap.m.Page control.

The following figure depicts the overall structure of the application. The homePageView is displayed initially and the detailPageView is displayed when drilling down to details. The appView only holds the sap.m.App control for page navigation. It has no visible user interface, but is always rendered as a sort of invisible frame containing the application.

228 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The HTML Page

The App_with_rootView.html page launches the application:

● It loads SAPUI5.● It ensures that all resources starting with sap.m.mvc, that is, the views and controllers are loaded from

locations relative to the HTML page.● It instantiates the root view and places it into the content div element.

Example for the HTML page:

<script id="sap-ui-bootstrap" src="../../../../resources/sap-ui-core.js" data-sap-ui-theme="sap_mvi" data-sap-ui-libs="sap.m" ></script>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 229

<script> // let UI5 know that certain package (the one containing the Views/Controllers) is available locally (next to the HTML file) sap.ui.localResources("sap.m.mvc");

// define View and place it onto the HTML page sap.ui.xmlview("appView", "sap.m.mvc.App").placeAt("content"); // all other initialization will be done by the App controller

</script>

The Root (App-) View

Although the root view and controller could be omitted by putting some code into the HTML file, this example shows how view are embedded into others to use MVC as much as possible.

The concept is simple: One sap.m.App control aggregates two sap.m.Pages. The first page is displayed initially:

<core:View controllerName="sap.m.mvc.App" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml">

<App id="theApp"> <mvc:XMLView id="homePageView" viewName="sap.m.mvc.HomePage"></mvc:XMLView> <mvc:JSView id="detailPageView" viewName="sap.m.mvc.DetailPage"></mvc:JSView> </App>

</core:View>

The viewName elements define the view type and the location, from which the respective view is loaded. The AppView also defines a controllerName, so a controller is loaded and attached as well.

The Root (App-) Controller

The root controller handles the following actions:

● It loads the data from a JSON file by using an AJAX call and initializes the overall JSONModel.● It handles the page navigation by listening to events published by the views and triggers the appropriate

navigation on the app control by using the EventBus.

When the user taps a list item on the homePageView, it publishes a to event in the nav channel. The root controller then executes the navToHandler method. After loading the view, if necessary, the root controller calls this.app.to(data.id, data.data.context) to trigger the navigation to the second page and to hand over the bindingContext, which contains information about the item the user selected on the initial page.

This leads to a horizontal slide animation. This is the default setting, but other animations can be chosen as well.

The back navigation is handled similarily, but is more simple, as no data needs to be passed. The app control keeps track of the page stack and automatically navigates back to the homePageView, using an inverse animation.

sap.ui.controller("sap.m.mvc.App", {

onInit : function() { var view = this.getView();

// Data is fetched here jQuery.ajax("Data.json", { // load the data from a relative URL (the

230 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Data.json file in the same directory) dataType: "json", success: function(data){ var oModel = new sap.ui.model.json.JSONModel(data); view.setModel(oModel); } });

// remember the App Control this.app = view.byId("theApp");

// subscribe to event bus var bus = sap.ui.getCore().getEventBus(); bus.subscribe("nav", "to", this.navToHandler, this); bus.subscribe("nav", "back", this.navBackHandler, this); },

navToHandler : function(channelId, eventId, data) { if (data && data.id) { // lazy load view if (this.app.getPage(data.id) === null) { jQuery.sap.log.info("now loading page '" + data.id + "'"); this.app.addPage(sap.ui.jsview(data.id, "sap.m.mvc." + data.id)); } // Navigate to given page (include bindingContext) this.app.to(data.id, data.data.context); } else { jQuery.sap.log.error("nav-to event cannot be processed. Invalid data: " + data); } },

navBackHandler : function() { this.app.back(); }});

The HomePage Controller

The HomePage controller handles the tap on a list item by publishing the event to the nav channel and hands over the relevant view (DetailPage) and the context of the tapped list item.

sap.ui.controller("sap.m.mvc.HomePage", {

listItemTriggered: function(evt) { // Option 1: using custom data attached to the ListItem // The ID (abbreviation) of the country is available as a custom data object and... // ...we could use it to fetch detail data // ...or we could hand it over to the detail page with .to("detailPage", {id: id}); var id = evt.oSource.data("id"); // this id remains unused in this example, though!

// Option 2: // In case of data binding we can get the binding context (a sort of pointer to the data object to which the clicked ListItem is bound) var bindingContext = evt.oSource.getBindingContext(); // evt.oSource is the ListItem

// The EventBus is used to let the Root Controller know that a navigation should take place. // The bindingContext is attached to the data object here to be used in the Root Controller's event handler.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 231

var bus = sap.ui.getCore().getEventBus(); bus.publish("nav", "to", { id : "DetailPage", data : { context : bindingContext } }); }});

The HomePage View

The HomePage view contains the content, which is displayed initially. It contains a full screen page control which displays a list of countries. The list is made from a StandardListItem template using SAPUI5 data binding. For each country in the data, one list item is created and displayed.

When you tap a list item, the attribute tap="listItemTriggered" calls the listItemTriggered method of the HomePage controller.

<core:View controllerName="sap.m.mvc.HomePage" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml">

<Page id="homePage" title="Countries"> <List items="{/countries}"> <StandardListItem title="{name}" description="{short}" type="Navigation" tap="listItemTriggered"> <customData> <!-- this is an OPTIONAL way to bind additional data to each list item; when the item is tapped, this data is read in the Controller --> <core:CustomData key="id" value="{short}" /> </customData> </StandardListItem> </List> </Page>

</core:View>

The DetailPage View

To give an example for other view types as well, the detail page of this example is build as a JSView. As usual for JSViews, the createContent method constructs the user interface of the view which contains one sap.m.Page control containing a List and a VBox layout. The List displays the details for the selected country. By using data binding it is ensured that the correct country data is displayed without actively fetching this data.

Triggering Back Navigation

While the semantics of the button on the left hand side of the page header is different between platforms ("back" button on iOS, "up" button on Android), the sap.m.Page only offers a navigation button and it is up to the application whether there is a difference between "up" and "back" on the respective page or whether it follows the platform guidelines and respects the difference.

In our example, "up" is the same as "back" and we only display this button with the label Countries (appears only on iOS). When the button is tapped, the method backTriggered of the view controller is called. The second array entry is the context of this method: When the method is executed, "this" is the controller.

var oPage = new sap.m.Page({ title:"Details",

232 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

showNavButton:true, navButtonText: "Countries", navButtonTap:[oController.backTriggered,oController]});

An application can also take shortcuts, for example, by directly calling app.back() if the "app" object is known inside the view. This demo application, however, wants to demonstrate maximum decoupling.

Handling the Navigation Event

Pages, or rather children of NavContainer/App controls such as this detail view, are informed about navigation activities. You can attach delegates to these pages for preparation and cleanup work. These delegates are also informed about the navigation activities. For more information, see Navigation and Lifecycle Events in the App and the NavContainer.

To updates the data binding every time before it is displayed, the detail view registers for beforeShow and sets the binding context which has been passed by the root controller as payload data of the to(…) call, which triggered the detail page navigation.

this.addEventDelegate({ onBeforeShow: function(evt) { this.setBindingContext(evt.data); // evt.to is actually this View (the navigation target). This should be "this" in the future to be more intuitive... }}, this); // give this (= the View) as additional parameter to make it available inside the delegate's functions as "this" object

The beforeFirstShow event can be used in a similar way by the application to lazily construct the UI only when it is actually required due to the user navigating to this page. Currently, the view UI creation in createContent is executed on application startup.

The Entire View Code

sap.ui.jsview("sap.m.mvc.DetailPage", {

getControllerName: function() { return "sap.m.mvc.DetailPage"; },

/** * Creates the UI of this View * * @returns {sap.ui.core.Control} */ createContent: function(oController) {

var oPage = new sap.m.Page({ title:"Details", showNavButton:true, navButtonText: "Countries", navButtonTap:[oController.backTriggered,oController] });

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 233

// create the page content structure jQuery.sap.require("sap.ui.core.format.NumberFormat"); var oList = new sap.m.List({headerText: "Country Details", items: [ new sap.m.DisplayListItem({label:"Capital:",value:"{detailInfo/capital}"}), new sap.m.DisplayListItem({label:"Population:",value:{ path:"detailInfo/population", formatter:function(iValue){ var oFormatter = sap.ui.core.format.NumberFormat.getIntegerInstance({ // format the population count groupingEnabled: true, groupingSeparator: "." }); return oFormatter.format(iValue); } }}), new sap.m.DisplayListItem({label:"Currency:",value:"{detailInfo/currency}"}), new sap.m.DisplayListItem({label:"Area:",value:{ path:"detailInfo/area", formatter:function(iValue){ var oFormatter = sap.ui.core.format.NumberFormat.getIntegerInstance({ // format the area groupingEnabled: true, groupingSeparator: "." }); var formattedNumber = oFormatter.format(iValue); return formattedNumber + " sq km"; } }}) ]}); oPage.addContent(oList); var oFlagArea = new sap.m.VBox({ alignItems: sap.m.FlexAlignItems.Center, items: [ new sap.m.Label({text:"Flag:"}), new sap.m.Image({src:"{detailInfo/flagUrl}",decorative:true,densityAware:false}) ] }); oPage.addContent(oFlagArea);

this.addEventDelegate({ onBeforeShow: function(evt) { this.setBindingContext(evt.data); // give this (= the View) as additional parameter to make it available inside the delegate's functions as "this" object } }, this);

return oPage; }

});

The DetailPage Controller

The DetailPage controller only contains the method for publishing the back event to the nav channel of the EventBus. The root controller listens to this event and triggers back navigation.

sap.ui.controller("sap.m.mvc.DetailPage", {

backTriggered: function() { var bus = sap.ui.getCore().getEventBus();

234 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

bus.publish("nav", "back"); }

});

1.1.3.19.3 Handling Navigation and Lifecycle Events

Mobile apps are often composed of several pages and the user can drill-down to detail pages and go back up again. This is often visualized by horizontal slide animations. SAPUI5 supports this pattern by providing the sap.m.App and sap.m.NavContainer controls, which handles the navigation between the pages.

sap.m.App inherits the navigation capabilities from the sap.m.NavContainer control. Thus, both controls are equal with regard to navigation and navigation events. The following sections refer to the sap.m.NavContainer, but the same also applies to the sap.m.App control.

A mobile application can control the navigation flow centrally and directly trigger the initialization or refresh of the pages. To support modularization of the app, however, it may also be beneficial to control the navigation flow non-centrally. In this case, code which constructs a page is also the code that handles, for example, the data load in this page.

To support this, SAPUI5 provides two types of events:

● Events fired by the App or by the NavContainer whenever it navigates.● Events fired on the pages when they get shown or hidden by navigation.

API References

● sap.m.App

● sap.m.NavContainer

Related Information

Events Fired Centrally by the App or the NavContainer [page 236]When NavContainer.to(…) or NavContainer.back(…) are called, the NavContainer triggers events and the application can register for this events. The navigate event is fired before the transition animation starts, and the afterNavigate event is fired when the animation has been completed.

Events fired on the Pages [page 236]

Passing Data when Navigating [page 237]When you use the to(…) and back(…) methods of the NavContainer to trigger navigation, you can also give an optional payload data object.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 235

Events Fired Centrally by the App or the NavContainer

When NavContainer.to(…) or NavContainer.back(…) are called, the NavContainer triggers events and the application can register for this events. The navigate event is fired before the transition animation starts, and the afterNavigate event is fired when the animation has been completed.

The events contain a lot of information about the page that is left and the target page of the navigation, as well as what kind of navigation is happening.

Example:

app.attachNavigate(function(evt) { var isBack = !evt.getParameter("isTo"); // there are several types of back animation, but we want the general direction only alert("Navigating " + (isBack ? "back " : "") + " to page " + evt.getParameter("toId"));});

API References

● event:afterNavigate

● event:navigate

Events fired on the Pages

Events fired on the pages allows a decentral reaction to navigation. The NavContainer fires events to its child controls regardless of whether they are displayed or hidden.

NoteAlthough this documentation calls them "pages" and a sap.m.Page control may be the typical child of a NavContainer, any full screen control can be used, for example, a sap.m.Carousel control or a custom control. Thus, the event is not fired by the child control, but by the NavContainer on the child control (whatever type it is). This causes the different registration compared to normal control events.

Before the navigation animation starts, the NavContainer fires the following events:

● beforeHide on the page which is about to be left● beforeFirstShow on the page which is about to be shown; this event is only fired if the respective page has

not been opened before● beforeShow on the page which is about to be shown

These events can be used to create or update the user interface of the new page and to stop any activity, such as animations or repeated data polling, on the page which is left.

236 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

After the navigation has been completed and the new page has covered the whole sccreen, the following events are fired:

● afterShow on the page which is now shown● afterHide on the page which has been left

You can destroy the hidden page, and the now active page can start its activity.

You can use the addEventDelegate function to register to these events. This function is available on every control.

page1.addEventDelegate({ onBeforeShow: function(evt) { // page1 is about to be shown; act accordingly - //if required you can read event information from the evt object }, onAfterHide: function(evt) { }});

API Reference

sap.m.NavContainerChild

Passing Data when Navigating

When you use the to(…) and back(…) methods of the NavContainer to trigger navigation, you can also give an optional payload data object.

This object is then available in the page events, for example beforeShow and afterShow. You can also use this mechanism to decouple page implementations.

Example:

app.to("detailPage", {id:"42"}); // trigger navigation and hand over a data object// this data object could also be a binding context when dealing with data binding// and where the detail page is implemented:myDetailPage.addEventDelegate({ onBeforeShow: function(evt) { var idToRetrieve = evt.data.id; // ...now retrieve the data element with the given ID and update the page UI }});

When you navigate back to a page, it receives the original data object which has been given when you first navigated to the page, but you can also give an additional data object with the back navigation.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 237

API References

● sap.m.NavContainer

● sap.m.NavContainerChild

1.1.3.19.4 Adapting to Platform and Form Factors

The SAPUI5 Mobile library target devices run different operating systems and have very different screen sizes and pixel densities. SAPUI5 does some adaptations automatically. In addition to that, the application can further adapt to the current device.

The following sections give an overview of the adaptations done by SAPUI5 and which adaptations you can implement in addition.

Related Information

Built-in Adaptation of SAPUI5 Mobile [page 238]

Adapting Automatically to Different Screen Sizes using SplitApp [page 240]Using SplitApp you can ensure that your UI automatically adapts to the size available on the respective device.

Checking the Operating System your Application is Running on [page 247]A platform attribute is added to the HTML tag when running on mobile devices.

Options for further Adaptation [page 248]

Built-in Adaptation of SAPUI5 Mobile

Platform-dependent Styling

The sap_mvi ("Mobile Visual Identity") theme delivered with the SAPUI5 Mobile library provides three different visual styles which closely mimic the native look of the Apple iOS, the Android, and the Windows Phone platform. Compared to the native visuals they are adapted to match the SAP color scheme with black and golden color accents.

NoteThe mobile visual identity (sap_mvi) theme is not supported for iOS7 and higher.

238 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● The iOS design has the typical Apple gradients and rounded corners, but is tinted in black and grey with golden accents.

● The Android design is using the Android 4.0 ("Ice Cream Sandwich") design with rather flat elements with no gradients or rounded corners. While the ICS design already uses black color, the MVI theme adds golden accents while maintaining Google's original blue style in the interactive controls

● The Windows Phone design mimics the typical chrome-less visuals, but does not adapt the entire interaction to feel 100% native.

The controls look very much like the native UI controls on these platforms, so the user immediately recognizes them.

NoteFor BlackBerry 10 the Android look and feel is currently used.

Other Platform-dependent Adaptations

In addition to the visual design, the SAPUI5 Mobile library provides further platform adaptations. To a certain degree, controls automatically adapt to the native UI concepts and user experience without any effort on application side.

The following list gives examples:

● The sap.m.Page control by default creates a header which looks different on both platforms even though there is only one single Page API:

○ On iOS, the navigation button is the typical Apple back button with a label and an arrow shape on the left hand side and the header title is positioned in the center.

○ On Android, the navigation button appears as an arrow with no label; an optional icon is displayed next to it and the header title is displayed left-aligned.

○ On Windows Phone, no back navigation button is available. Instead, the phone's hardware button is used for back navigation.

● When used in a bar on Android, the sap.m.SegmentedButton looks like a tab.● The sap.m.Dialog appearance not only differs between operating systems, but also between form factors:

○ On Android, it is a bright popup with buttons filling the whole popup footer.○ On iPad, it is a popup with dark header and buttons in the left and right side of the header.○ On iPhone, it looks like on iPad, but covers the full screen and is sliding in from the bottom.

The SplitApp Control - Adapting Automatically to Different Form Factors

You can use the sap.m.!SplitApp control to implement multi-page scenarios that automatically adapt to the available screen size: On phones, only one page is displayed, and on tablets, especially in landscape orientation, two pages are displayed simultaneously.

For more information, see SplitApp - Hello World.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 239

Adapting Automatically to Different Screen Sizes using SplitApp

Using SplitApp you can ensure that your UI automatically adapts to the size available on the respective device.

As tablets such as iPad or Google Nexus7 provide more space compared to smartphones, porting existing mobile apps to tablets leads to a lot of unused space.

A common pattern to address this is called master-detail, and is often used in native iOS and Android development. Good examples are the native Settings and E-Mail applications of iOS and Android tablets. This pattern can be used with the SplitApp control.

The figure shows the basic idea of the pattern. The app is divided into two views, the master and the detail view. The master view presents a list of items and is used as the main navigation within the application. The detail view shows detail information for the selected item.

Whereas the selection of an item on a mobile devices navigates the user to the detail page, the user can see the list of items and the detail view at the same time on a tablet device.

If the tablet device is used in protrait mode it has less available width space. For this, the SplitApp control provides three different modes for displaying the master and detail view in portrait mode:

● ShowHideModeThis is the default mode. This mode hides the master view automatically when the user turns the device into portrait mode. To display the master view, the user swipes right on the detail view or uses the button which is be placed on the header of the detail view.The Master view slides in from the right hand side. The user can choose another list item which will update the detail view and automatically hides the master view again.

● PopoverModeThis mode places the master view inside a popover which can be opened via the button in the header of the detail view.

● StretchCompressMode

240 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

This mode displays the master view in both, the portrait and the landscape mode. In portrait mode, the detail view has less space available.

In landscape mode, all three modes described above display the master view.

If you run a SplitApp on a mobile device, it automatically behaves like a standard mobile application. The following figure shows the difference:

As only one page per screen can be displayed, the master and detail view are automatically displayed on separate pages and the standard page navigation is applied.

The following section explains how a SplitApp application is build, see The First SplitApp.

The First SplitAppTo develop a SplitApp application, use the sap.m.SplitApp control instead of the sap.m.App control which is used for smartphone applications only.

NoteRunning Demo

This demo app shows how you can automatically adapt your user interface to the available space by using the SplitApp control.

On a mobile phone, pages are stacked on top of each other and linked via navigation. On a tablet PC with landscape orientation, the pages are shown next to each other in a split view layout whereas in portrait orientation the application can choose whether to always display the master view, to display it in a popover, or to display it when the user swipes from the left. In this Demo App, you can try all three modes. Just open the iPad or Android tablet version in a new window, size it to portrait mode and choose the display mode on the bottom left.

To launch it, choose SplitApp from here: Demo Apps .

var oSplitApp = new sap.m.SplitApp("mySplitApp", {});

You can add pages to the SplitApp control, but you have to decide to which view you want to add them:

oSplitApp.addDetail() or oSplitApp.addMaster();

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 241

Before you can do this, you need some basic pages, two for the Master and two for the Detail view:

var oDetailPage1 = new sap.m.Page("detail1", { title : "Detail 1", content : [ new sap.m.Label({ text : "this is Detail 1" }) ]});var oDetailPage2 = new sap.m.Page("detail2", { title : "Detail 2", content : [ new sap.m.Label({ text : "this is Detail 2" }) ]});

To implement a basic navigation for selection of the Detail view, the two Master view pages need a list. As we only need to navigate or drill down inside the Master view, a simple StandardListItem with type Navigation is sufficient.

If the user taps on a list item, we navigate to Master view page 2. To do this, call the toMaster() method with the page you want to navigate to. In the example this is master2.

var oMasterPage1 = new sap.m.Page("master1",{ title : "Master", content : [ new sap.m.List({ items : [ new sap.m.StandardListItem({ title : "To Master 2", type : "Navigation", tap : function() { oSplitApp.toMaster("master2"); } })] }) ]});

The second Master view page is the leaving point of the master navigation: Depending on the item the user selects, the Detail view is updated. An example for this is an e-mail application with a list e-mails in the Master view and the content of the e-mail in the Detail view.

As we do not want to further navigate within the Master view, the list mode is set to SingleSelectMaster.

To update the Detail view, we have to listen to the list's select events, so we can decide on which detail page to show. Depending on the selected list item, either the detail1 page or the detail2 page is displayed. The method is called toDetail.

var oMasterPage2 = new sap.m.Page("master2",{ title : "Master2", navButtonTap : function() {oSplitApp.backMaster();}, content : [ new sap.m.List({ mode:"SingleSelectMaster", select: function(oEv) { if(oEv.getParameter("listItem").getId() == "listDetail2") { oSplitApp.toDetail("detail2"); } else { oSplitApp.toDetail("detail1"); } }, items : [ new sap.m.StandardListItem("listDetail2",{ title : "To Detail 2" }), new sap.m.StandardListItem("listDetail",{

242 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

title : "To Detail 1" }) ]}) ]});

To enable the SplitApp to run on mobile devices, some additional information needs to be added to the pages. Also, the navigation back to the Master view page has to be available from both Detail view pages.

In the next step, the pages are put into the SplitApp control:

//add the master pages to the splitapp controloSplitApp.addMasterPage(oMasterPage1).addMasterPage(oMasterPage2);//add the detail pages to the splitapp controloSplitApp.addDetailPage(oDetailPage1).addDetailPage(oDetailPage2);

Then set the initial Master view and Detail view page:

oSplitApp.setInitialDetail("detail1");oSplitApp.setInitialMaster("master1");

Define the page transition type you want to use, see Navigation and Lifecycle Events in the App and the NavContainer.oSplitApp.setDefaultTransitionNameDetail("fade");Finally, place the SplitApp control in the HTML body tag:

oSplitApp.placeAt("body");

To test the other two SplitApp modes, use the setMode method to set them:

oSplitApp.setMode("PopoverMode");//oroSplitApp.setMode("StretchCompressMode");

Layouting with FlexBox

User interfaces often have to adapt to different screen sizes. Therefore, building user interfaces in a way that a single layout reliably fits the available screen real estate is challenging. The FlexBox control allows to develop layouts which adjust to the available space and avoid unused space or overflow. FlexBox controls can be nested to create more complex layouts.

The two main uses of a FlexBox control are:

● Two-dimensional layouting● Flexible layouts

Getting Started With FlexBox

To use a flexible box layout, create a FlexBox control and add any kind of controls to it, either by using the addItem method (see option 1), or the items aggregration of a configuration object (see option 2).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 243

Option 1

var oMyFlexbox = new sap.m.FlexBox();oMyFlexbox.addItem( new sap.m.Button({text: "Button 1"}) );oMyFlexbox.addItem( new sap.m.Button({text: "Button 2"}) );

Option 2

var oMyFlexbox = new sap.m.FlexBox({ items: [ new sap.m.Button({text: "Button 1"}), new sap.m.Button({text: "Button 2"}) ]});

The following figure gives an example how the result looks like if used inside a mobile app page. The necessary code is not shown here.

Layout properties

Some properties that affect the layout need to be set in the FlexBox control. Other properties can be attached to the controls which are placed inside the FlexBox by means of the layoutData aggregation. The layout direction, for example is set in the FlexBox as follows:

var oMyFlexbox = new sap.m.FlexBox({ items: [ new sap.m.Button({text: "Button 1"}), new sap.m.Button({text: "Button 2"}) ], direction: "Column"});

The order is attached to the button inside a FlexItemData object as follows:

var oMyFlexbox = new sap.m.FlexBox({ items: [ new sap.m.Button({

244 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

text: "Button 1", layoutData: new FlexItemData({order: 2}) }), new sap.m.Button({text: "Button 2"}) ]});

NoteThe FlexBox control is a wrapper for the flexible box layout properties in CSS. The control renderer sets the CSS properties (including prefixed versions where necessary) on the appropriate HTML elements. The actual layouting is done by the browser.

The controls that you place in the FlexBox control are each wrapped in a DIV or LI element, depending on the renderType property. All elements are placed inside another DIV or UL container, again depending on the renderType. The outermost element represents the so-called flex container while its child elements are flex items. The HTML structure resulting from all of the examples above looks as follows:

<div class="sapMFlexBox">

<div class="sapMFlexItem">

<button id="__button1">Button 1</button>

</div>

<div class="sapMFlexItem"> <button id="__button2">Button 2</button>

</div></div>

NoteThe layoutData properties that you can attach to a control are applied to its wrapper element with sapMFlexItem class. This is because browsers currently only support these properties on some elements, for example DIV.

The two additional controls HBox and VBox are FlexBoxes that are fixed to horizontally or vertically layout their children.

Important FlexBox Layout Concepts

The following sections contain information about important concepts for FlexBox layouts.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 245

Main Axis and Cross Axis

A FlexBox layout has a direction in which child elements are laid out. The default direction is Row and rows are laid out horizontally in reading direction. This defines the main axis. The cross axis in this case is vertical.

You can change the layout direction property to Column, which results in a vertical main axis and a horizontal cross axis. This is important for the align properties.

NoteIf browsers support vertical text flows, the direction of a row can also be vertical. For now this is not an issue and can be ignored.

In addition to Row and Column, the flex direction can be set to RowReverse and ColumnReverse which will reverse the layout direction.

Two-Dimensional Alignment

You can determine where the flex items are aligned in a FlexBox layout. For the alignment you use the following two properties: justifyContent and alignItems. The justifyContent property sets the alignment along the main axis while alignItems acts on the cross axis.

Both properties accept the values Start, Center and End. This results in nine possible combinations, for example

● justifyContent = End and alignItems: Start places the items in the upper right corner of a horizonzal FlexBox● If you set the direction property to Column, the main axis would be vertical. Combined with justifyContent =

End and alignItems: Start, the items are placed in the lower left corner.● By reversing the main axis with direction = ColumnReverse the layout starts from the bottom. In this case,

justifyContent = End refers to the top of the FlexBox.● justifyContent has the additional value SpaceBetween?. This setting places the first and the last item at the

extremes of the main axis. Any other items will be distributed evenly between these two.

For alignItems two additional values exist: Baseline and Stretch. Baseline takes the first line of text of each flex item and aligns their baselines. This can be useful if different font sizes are used. Stretch makes the flex items take up the whole space along the cross axis of the FlexBox. This is useful if all items should have the same size regardless of the amount of content.

Flexibility

You can let the browser handle the distribution of elements. This ensures that they always fill the available space along the main axis. To do this, set a flexibility factor on the flex items.

The property to control the flexibility is called growFactor. It is set on a flex item object by means of FlexItemData on the layoutData aggregation. The flex layout algorithm determines the "natural" width of the flex items. If there is space left, this space is distributed among the flex items according to their relative growFactor. If, for example, a horizonzal flex container is 300px wide and contains two elements of 100px each, 100px would remain. If the growFactor for both flex items is set to 1, both get 50px extra, thus making them

246 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

150px wide. If the growFactor is set to 3 for one item and to 1 for the other item, the first item gets additional 75px (¾ of 100px) of the remaining space and the second item 25px (¼ of 100px). If the growFactor is set to its default value of 0, the item is inflexible and both items would keep their width of 100px.

NoteThe the flex algorithm distributes the remaining space, and not the whole space in the FlexBox. Therefore, the resulting widths of the items are not necessarily proportional to the growFactor.

To achieve a proportional width according to the growFactor, set the width of all items to 0 via CSS. The sum of the "natural" widths of all items is then also 0. The remaining space, however, now equals the full space of the FlexBox. This space is then distributed based on the growFactor. For the example above with growFactor set to 3 and 1, setting the the width of the flex items to 0 via CSS results in a width of 225px (¾ of 300px) for the first item and 75px (¼ of 300px) for the second item.

CautionOnce you set a growFactor for any item, the flex layout algorithm ignores the justifyContent property of the FlexBox because the items take up all available space anyway. There would be no difference between the different values.

Checking the Operating System your Application is Running on

A platform attribute is added to the HTML tag when running on mobile devices.

This attribute provides information about the current platform and version. For an application running on an iPad3, for example, the attribute value is iOS5.1.

NoteSAPUI5 Mobile currently only supports iOS, Android, Windows Phone 8 and Blackberry 10.

In addition to that, SAPUI5 adds a platform-dependent CSS class to the HTML tag of the page. This enables control or application developers to create platform-dependent styling for their controls or applications.

Technical Details

When the SAPUI5 bootstrap script file is loaded, a check is performed to see if the application is running on a mobile platform. If this is the case, the attribute and CSS classes are added to the HTML tag. The platform attribute value has the following connotation: Operating system + version, for example iOS6.0, Android4.1.1, bb10.0.9.2372, winphone8.0. Operating system can have the following values:

● iOS (Apple devices)● Android (Android devices)● bb (BlackBerry)

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 247

● winphone (Windows Phone)

The version numbers are separated by dots. The possible values for the CSS class are:

● sap-ios (Apple devices)● sap-android (Android devices)● sap-bb (BlackBerry)● sap-winphone (Windows Phone)

The platform attribute or CSS class is used as follows:

● To provide a different font on Android devices, you specify your font by directly using the CSS class sap-android.

.sap-android{ font-family: Roboto;}

● Example for providing a different font when running on Android 2.x:

html[data-sap-ui-os^='Android2'] .sap-android{ font-family: "Droid Sans";}

Options for further Adaptation

In addition to the adaptations done automatically by SAPUI5, the application can apply further platform adaptations. To facilitate these adaptations, SAPUI5 provides a variety of detection mechanisms.

Mobile vs Desktop

It is getting more and more difficult to detect for the application whether it runs on a desktop or on a mobile device: Some Desktop computers support touch operations, keyboards can be attached to tablets, and you can detach laptop screens to use them as tablets.

Depending on your own definition of the distinction between desktop and mobile, you can detect touch capabilities, for example, by checking the following:var isTouchDevice = jQuery.support.touch;Based on this check, SAPUI5 provides also the following flag:var runningOnDesktop = jQuery.device.is.desktop;Other possibilities include checking the screen size or whether certain APIs or features are available.

248 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Phone vs Tablet

The distinction between phone and tablet is also becoming more and more difficult as the phone sizes are growing and almost approach tablet sizes.

The current definition is that a device is a phone rather than a tablet as long as size of the screen is smaller than 600 pixels. This definition is used by the jQuery.device.is.tablet flag.

var runningInTablet = jQuery.device.is.tablet;The flag also contains additional information, such as:

● iphone, ipad: Flags whether the application runs on either of them● Desktop, phone: Alternatives to "tablet" (the distinction between desktop and tablet is made by checking

touch capabilities)

For more information, see

In the CSS, you can use CSS media queries to check screen sizes.

iOS vs Android and Version Information (as JavaScript API)

The jQuery.os object contains information about the operating system:

● os: Operating system as string ("ios", "android", "winphone", or "blackberry")● ios, android, winphone, blackberry: Boolean flags for the respective platform● version: Operating system version as string● fVersion: Operating system version as float

For more information, see

iOS vs Android vs Windows Phone vs BlackBerry - and Version Information (for CSS styling)

SAPUI5 also adds platform and browser version information to the root element (the <html> element of the page). There are different three information packages:

● The CSS class "sap-ios", "sap-android", "sap-winphone", or "sap-bb" (for BlackBerry) is added for easy platform-dependent styling.

● The attribute "data-sap-ui-browser" is added, providing more information about browser and version.● The attribute "data-sap-ui-os" is added, providing more information about operating system and version.

You can use the CSS class directly in cascades, the other two need attribute selectors which can also be used to match substrings:

.sap-ios .myControl { color: red; /* make my control red on Apple devices only */}

html[data-sap-ui-browser*=msf] .myControl {

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 249

background-color: blue; /* Control should have a blue background whenever Mobile Safari is running... */}

html[data-sap-ui-os="iOS5.0"] .myControl { background-color: green; /* ...but when running on an Apple device with version 5.0 of the operating system, it should rather be green */}

For more information, see Platform Attribute for Mobile.

Orientation and Change of Orientation

The jQuery.device.is object contains information about the page orientation:

● landscape: Flag indicating whether the current orientation is landscape● portrait: Flag indicating whether the current orientation is portrait

For more information, see

If the orientation is changed, because the user rotates the device, the browser fires the orientationchange event. In some cases, this event seems to be delayed, and, therefore, the sap.m.App control fires its own orientationChange event based on the browser's window resize event:

myApp.attachOrientationChange(function(evt) { if (evt.getParameters().landscape) { // do something... }});

In CSS, you can use CSS media queries to check this.

1.1.3.19.5 Working with Lists

List

List can have the following properties:

● modeThis property defines in which way the left area of a list item will appear. You can show a single selection, multi selection, delete buttons, or none of these.The mode property can have the following values:

○ None (default)○ SingleSelect (on the right side)○ SingleSelectLeft (on the left side)○ SingleSelectMaster (without select control for use cases like the split app, by default the !

includeItemInSelection = true)

250 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

○ MultiSelect○ Delete

● includeItemInSelection (default: false)This property defines the tap handling of a list item. By default, you can select an item by tapping the radio button or check box. To use the whole list item tap for selecting an item, change the property value to 'true'. This property is only relevant in selection mode.

● showUnread (default: false)This property decides whether an 'unread' indicator is added to each list item. When active, it shows a blue bubble for unread list items.

● showNoData (default: true)If set to 'true', a text is shown to the user if a list has no content . The default text is 'No data'. You can use the noDataText property to change the default text.

● noDataText (default: 'No data')

Swipe For Action

A user can swipe left on a list item to bring in a control, for example a button, and initiate an action for this item. This control is defined through the swipeContent aggregation of the list and will be displayed on the right or center of the list item. For more information, see Swipe List for Action.

List Events

For selection, deletion and swiping in lists, events are needed. The selection mode fires a 'select' event and the deletion mode a 'delete' event. A swipe left fires a 'swipe' event. These events contain information about the list item that caused the event.

● select (listItem)● delete (listItem)● swipe (listItem), see Events

Rerendering

A list including all its list items is rerendered when the data of a bound model is changed. Due to the limited hardware resources of mobile devices this can cause delays for lists with many list items. Therefore, we do not recomment the use of a list for these use cases.

ListItemBase

All SAPUI5 list items inherit from ListItemBase. It contains the navigation, selection and event features.

Five different types are available, which determine the way a list item is interacting. A list item has a content area (main area) which may fire a tap event and a navigation area on the right hand side, which may fire a tap or a detailTap event. The "type" property for each list item defines the events which are fired. This needs to be configured because it also decides the visual feedback a list item gives when touched.

NoteBy default, a list item does not fire an event unless it is configured with a type that defines how events are fired. An exception to this ActionListItem.

The following table shows the different combinations of list item types and events:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 251

type tap event detailTap event icon active feedback

Inactive (default) -- -- -- --

Active yes -- -- yes

Navigation yes -- > yes

Detail -- yes (>) --

DetailAndActive yes yes (>) yes (only content)

ListItemBase has a 'unread' indicator property (default: false), which shows a blue bubble. This has to be enabled in the showUnread property. For the selections on each list item a selected property (default: false) exists. Another feature is the counter property (default: null), which shows integer numbers except zero. If the number is zero, the counter will be hidden.

● unread (default: false)● selected (default: false)● counter (default: undefined)

ActionListItem

The ActionListItem inherits all features from the ListItemBase and provides the following additional feature:

A text can be set, which will be center aligned.

text

this is a simple list item for triggering actions.

CustomListItem

This is a simple list item for triggering actions.

The CustomListItem inherits all features from the ListItemBase and provides following additional feature:

content can be aggregated.

The CustomListItem can be used for all list items SAPUI5 does not provide. You can build your own content and aggregate it.

Custom HTML

An easy way to cover simple CustomListItems is to add an HTML control, in which you can write your HTML either directly, or if you use a model and data binding, you can use a formatter to integrate it between the HTML.

Example: We have a model with first name, last name, age, and city properties. We create a CustomListItem, add a HTML control to the list item content and than write a formatter with our HTML code:

var myCustomListItem = new sap.m.CustomListItem({ content: new sap.ui.core.HTML({ content: { parts: [ {path: "firstName"},

252 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

{path: "lastName"}, {path: "age"}, {path: "city"} ], formatter: function(firstName, lastName, age, city) { return "<div><div class='myStyleClass'>Name: " + firstName + " " + lastName + "</div><div>Age: " + age +"</div><div>City: " + city +"</div></div>"; } }}), type : 'Navigation' //({type} if provided by the model) tap : myTapEvent});

CautionThis approach only works when you use JavaScript for the UI. When using a declarative model, such as XML Views, use an on-the-fly control, see Developing UI5 Controls in JavaScript.

DisplayListItem

The DisplayListItem inherits all features from the ListItemBase and provides the following additional features:

● label - for setting a label● value - for setting a value

InputListItem

The InputListItem inherits all features from the ListItemBase and provides following additional features:

● label - for setting a label● content - for content aggregation; you can set one of the following controls: Input button, radio button,

checkbox, slider, select, search

StandardListItem

The StandardListItem inherits all features from the ListItemBase and provides following additional features:

● title - for setting a title● descripton - for adding a description● icon - for adding an icon on the left hand side, which can be showen with or without an inset; the property

contains the icon source path to the location where all images for all device resolutions are stored● activeIcon - the property contains the icon source path for images that are shown while the list item is tapped● iconInset - default is 'false': Image takes the whole list item height; when set to 'true', the icon is rendered as

an inset

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 253

● iconDensityAware - when set to 'false', no checks for other resolutions are made; use this option if you do not want to provide icons with a specific resolution

1. An icon on the left side which can be shown with or without an inset.

2. A title can be set.

3. A description can be set.

● title● description● icon (Icon source path where all the images for each device resolution can be found.)● activeIcon (Icon source path for images which should be shown while the list item is tapped.)● iconInset (Default: false images takes the whole list item height, true for an inset.)● iconDensityAware (If you won't provide specific device resolution icons, set it to false. Therefore no checks fpr

other resolutions are made.)

Swipe for Action in Lists

If a user swipes left on a list item, you can bring in a control, for example a button, to initiate an action for this item. The button is displayed on the right hand side on center of the list item. An example is shown in the following figure.

Aggregation

This control is defined by the swipeContent aggregation of the list. You can add any control as swipeContent, but keep in mind that your content cannot be higher than a list item, see the following examples:

● Button swipeContent

var list1 = new sap.m.List({ swipeContent : new sap.m.Button({ text : "Approve", type : "Accept", tap : function() { /* ...approving code goes here... */

// we are done hide the swipeContent from screen list1.swipeOut(); } }) }), ...

254 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● Control combination as swipeContent

new sap.m.List({ swipeContent : new sap.m.HBox({ items : [ new sap.m.Image({ src : "images/edit.png", tap : ... }), new sap.m.Image({ src : "images/delete.png", tap : ... }) ] }), ...

Events

List provides a swipe event when a user swipes left to bring in a control on the right hand side of the list item. This event is fired before the swipeContent is shown and contains the following three important parameters:

● listItem : List item that fired the swipe event● swipeContent: Specifies the swipeContent control to show on the right hand side of a list item● srcControl: Specifies the control that fired the swipe event

This means that you can dynamically change the swipe content according to the respective list item. If a list item, for example, has not yet been approved, the Approve button is shown. After approval or if it is already approved, the Disapprove button is shown. See the following example:

var list1 = new sap.m.List({ swipeContent : new sap.m.Button({ text : "Approve", type : "Accept", tap : function() { /* ...approving code goes here... */

// we are done hide the swipeContent from screen list1.swipeOut(); } }) }), swipe : function(e) { // register swipe event var oSwipeListItem = e.getParameter("listItem"), // get swiped list item from event oSwipeContent = e.getParameter("swipeContent"); // get swiped content from event

// Check swiped list item if it is already approved or not if (oSwipeListItem.data("approved")) { // List item is approved, change swipeContent(button) text to Disapprove and type to Reject oSwipeContent.setText("Disapprove").setType("Reject"); } else { // List item is not approved, change swipeContent(button) text to Approve and type to Accept oSwipeContent.setText("Approve").setType("Accept"); } }, ...

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 255

Swipe events can be cancelled. The built-in controls which are working with swipe left events like Switch or Slider cancel a swipe event by default. If you also want to disable swipe events for your custom use case, you can call the preventDefault method of the event object. This is shown in the following example:

new sap.m.List({ swipe : function(e) { // get which control inside the list item fired swipe event var oSrcControl = e.getParameter("srcControl");

// check if the event is coming from Input if (oSrcControl instanceof sap.m.Input) { e.preventDefault(); // cancel swipe } }, ...

Methods

List provides the following two swipe methods:

● swipeOut( [callback] ): After swipeContent is shown, the user can interact with the control, for example tap it. After this interaction, for example on tap event, you can use this method to hide swipeContent from the screen. Per default, swipe for action works on auto hide mode. This means that if a user tries to tap inside the list but outside the swipeContent, then the swipeContent hides automatically. After you call this method, swipeContent hides with animation and if you need to run code after the animation you can simply add a callback function to this method as a first parameter.

● getSwipedItem(): This method returns the currently swiped list item. When no item is swiped, null is returned. The swipeContent events, for example tap, are a good place to use this method to get information for which list item swipeContent is shown.

The following example shows a delete scenario:

var list3 = new sap.m.List({ swipeContent : new sap.m.Button({ text : "Delete", type : "Reject", tap : function() { var oSwipedItem = list3.getSwipedItem(); // Get which list item is swiped to delete list3.removeAggregation("items", oSwipedItem); // Remove this aggregation to delete list item from list list3.swipeOut(); // we are done, hide the swipeContent from screen } }), ....

Properties

The swipeDirection property for lists is used to configure the direction of the swipe event. This property accepts an enumeration from sap.m.SwipeDirection? with the following values.

● LeftToRight?: Swipe from left to right● RightToLeft?: Swipe from right to left● Both: Both directions (left to right or right to left)

The default value is Both, but in some use cases we recommend to change this property, for example to prevent swipe conflicts.

256 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.19.6 Triggering Phone, SMS and E-Mail

With SAPUI5 for Mobile you can easily trigger native mobile phone applications such as e-mail, telephone, and text messages.

You can set predefined values for the application so that a user does not need to enter this information themselves. When personal information is displayed, for example phone numbers and e-mail addresses, you can initiate a phone call or e-mail with just one tap.

The URLHelper API contains the following triggers for telephone, texts, and e-mail applications:

● Trigger telephone application

sap.m.URLHelper.triggerTel( [Telephone Number] ); //Telephone number is optional

● Trigger text messaging application

sap.m.URLHelper.triggerSms( [Telephone Number] ); //Telephone number is optional

● Trigger e-mail application

sap.m.URLHelper.triggerEmail( [Destination Email], [Subject], [Default Message Text], [CC], [BCC] ); // All parameters are optional

● Redirect To custom URL

sap.m.URLHelper.redirect( URL ); //URL is required and can be used for custom protocols (e.g http, ftp, ...)

API Reference

● sap.m.URLHelper

Examples for Triggering Telephone, Text and E-Mail Applications

Sample data used in the examples:

var person = { name : "John Smith", tel : "+49 62227 747474", sms : "+49 173 123456", email : "[email protected]", website : "http://www.sap.com"};

You can trigger an external application at any time, but it is usually triggered as a reaction to a UI control throwing an event. The next sections illustrate some of the most typical use cases.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 257

Click Button To Trigger Phone Call

The following button can be used to place a call. The figure shows, how the button looks like.

new sap.m.Button({ text : person.tel, icon : "images/action.png", /* Depends where your images are located */ tap : function() { sap.m.URLHelper.triggerTel(person.tel); }});

Click Image To Trigger E-mail

The following code snippet gives an example for triggering an e-mail application. You can also set the subject and message of the e-mail application:

new sap.m.Image({ src : "images/website.png", /* Depends where your images are located */ tap : function() { sap.m.URLHelper.triggerEmail(person.website, "Info", "Dear " + person.name + ","); }});

Inside List

DisplayListItem with active feedback is the most popular use case for the following example.

new sap.m.DisplayListItem({ label : "Sms", value : "( " + person.sms + " )", type : "Active", tap : function() { sap.m.URLHelper.triggerSms(person.sms); }});

To use any other control inside the list, use InputListItem?:

258 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

new sap.m.InputListItem({ label : "Website", content : new sap.m.Button({ text : person.website, tap : function() { sap.m.URLHelper.redirect(person.website); } })});

Notes

● iOS does not trigger a phone call if the phone number contains "*" or "#".● You can add multiple recipients for a text message in Android phones by separating recipient numbers with

";".● According to RFC 2368 you can set multiple subscribers for the e-mail application by separating each with ",";

however, this still depends on the application. Outlook, for example, uses ";" as separator.● You can use the sap.m.URLHelper.redirect method to use custom URL schemes:

○ For iOS: http://developer.apple.com/library/safari/#featuredarticles/iPhoneURLScheme_Reference/

Introduction/Introduction.html

○ For Android: http://developer.android.com/guide/appendix/g-app-intents.html

○ URI schemes: http://en.wikipedia.org/wiki/URI_scheme● If you just want to get a URI back without a redirect, you can use normalize methods which have the same

parameter as trigger methods, for example:

/* * These methods do not redirect but return URI scheme back as string. * All parameters are optional */sap.m.URLHelper.normalizeTel( [Telephone Number] );sap.m.URLHelper.normalizeSms( [Telephone Number] );sap.m.URLHelper.normalizeEmail( [Destination Email], [Subject], [Default Message Text], [CC], [BCC] );

1.1.3.19.7 Scrolling in SAPUI5 Mobile

Because of limited size of mobile devices, scrolling is an essential topic in mobile user experience. Smooth and easy scrolling is important for user acceptance of mobile applications.

In general, application programmers do not need to take care of scrolling when using the sap.m control library. Scrolling is provided automatically by the following controls:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 259

● sap.m.Page● sap.m.Dialog● sap.m.Popover● sap.m.ScrollContainer

However, if you create a custom scrollable control, read the following sections.

Scrolling: Implementation Details

Unfortunately, scrolling support in mobile browsers is very weak and inconsistent. Only the newest platforms and browsers start to support partially usable scrolling functionality.

Hence, SAPUI5 embeds the open source livrary iScroll4 that takes care of scrolling in the application. Though the library is globally available in a SAPUI5 application, programmers should not call it directly. The sap.ui.core.delegate.ScrollEnablement delegate provides all functionality and smooth integration of iScroll4 into the SAPUI5 library.

For more information, see

Do not use nested scrolling

We do not recommend to use nested levels of scrolling, for example, when a page with enabled vertical scrolling contains a scroll container that has vertical scrolling too. Such combinations may lead to behavior that is unexpected both for programmers and users.

Implement a custom scroll container

A custom control that needs to provide a scrollable area for its content should implement the following steps:

1. Instantiate a sap.ui.core.delegate.ScrollEnablement delegate, at best in the .onAfterRendering callback.

2. Implement a .getScrollDelegate method that returns the current instance of the delegate to other controls.

3. Destroy the ScrollEnablement delegate on exit.

Example:

myCustomScroller.prototype.onAfterRendering = function() { if(!this._oScroller){ jQuery.sap.require("sap.ui.core.delegate.ScrollEnablement"); // attach a scroller to the scrollable container DOM element this._oScroller = new sap.ui.core.delegate.ScrollEnablement(this, this._scrollContainerId, { horizontal: false, vertical: true });

260 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}};

myCustomScroller.prototype.getScrollDelegate = function() { return this._oScroller;};

myCustomScroller.prototype.exit = function() { if(this._oScroller){ this._oScroller.destroy(); this._oScroller = null; }};

NoteThough the SAPUI5 library includes also a Zynga scroller, it is an experimental alternative to iScroll4 that is not supported in SAPUI5 and may be used for testing only. The configuration parameter oConfig.zynga=true of the scrolling delegate should therefore not be used.

Interaction with the scroll containers

There are cases, when an embedded control controls scrolling of the parent container, if required. These are

● a sap.m.ScrollContainer inside a sap.m.Page may block parent scrolling, if it scrolls in the same direction itself;

● a sap.m.TextArea control in edit mode blocks parent scrolling, so that the user can scroll text contents during input;

● a sap.m.GrowingList control scrolls parent container to update positions of visible items after the new items have been loaded from the server.

When using a sap.m.FlexBox with fitContainer set to true inside of a page, the enableScrolling property of the page needs to be set to false for the FlexBox to fit the viewport.

Scrolling: Pull to Refresh

The SAPUI5 mobile library supports the "pull down to refresh" functionality that allows users to refresh lists or page content with fresh data from server.

To implement it, create a PullToRefresh control and put it as the first control into a page or a scroll container that contains the list that needs to be refreshed.

Example:var pullToRefresh = new sap.m.PullToRefresh({ description: getLastUpdatedTime(), refresh: function(){ pullToRefresh.setDescription("loading from server..."); //request new data from server getNewData({ // when data comes from server onSuccess: { pullToRefresh.hide();

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 261

pullToRefresh.setDescription(getLastUpdatedTime()); redrawList(); } }); }; The application should request new data on the refresh event and call the hide method when the data is received and the list is refreshed. You can provide a URL to a custom logo image with customIcon or switch display of logo of by setting showIcon to false. The first line of text "Pull to refresh" is standard and cannot be changed. However, you may set an optional description text to display, for example, the last update time.

NotePullToRefresh control is part of the scroll area and therefore its height is reflected in the scroll bar calculation and display. The user can see that the page can be scrolled down to reveal the pull-down area.

Carousel

Pull to Refresh does not work with a Carousel if both are contained in a page: in order to make Pull to Refresh work, the page has to enable scrolling which leads to problems with the Carousel (Carousel not visible). Suggested Workaround: Add a sap.m.PullToRefresh instance to each page that you add to your Carousel.

API References

sap.m.PullToRefresh

1.1.3.19.8 Running SAPUI5 Mobile Apps in Hybrid Web Containers

SAPUI5 provides the following two options for building mobile apps:

● Building the app as a web application loaded from a URL● Building the app as an hybrid app consisting of a native app wrapper, for example PhoneGap, and an HTML

viewer to display the SAPUI5 content on the user interface.

Hybrid apps have the advantage that you can publish them in app stores. Also, by embedding hybrid apps in the application code and the SAPUI5 library files in the hybrid container, you need to install the files only once and do not need to download them every time you start the application. But then the library size becomes important, because every user has to install the files, whereas in web applications the library is deployed on a server and you only need to download the required parts of the library at runtime.

To include the SAPUI5 resources you need in your hybrid app, use one of the following static packages for SAPUI5 mobile: sapui5-mobile-opt-static.zip or sapui5-mobile-static.zip. The library size of these packages is rather small because all unnecessary content has been removed, for example test pages. The packages contain the debug version as well as the optimized and minimized versions of all JavaScript files. Thus, you can use the packages for productive use as well as for debugging purposes. To use this package in an app

262 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

wrapper, such as PhoneGap, unzip the package in the respective resource location of the app development project. The app wrapper build then includes the files and makes them available at runtime.

Optimization of the Package Size

Although the static SAPUI5 package is small enough to be included in hybrid apps, you can reduce the size further and optimize the content for a specific application by deleting additional files. The following list gives some examples:

● You can delete one of the following files from the /resources folder depending on your setup: sap-ui-core-nojQuery.js if you reference SAPUI5 normally or sap-ui-core.js if you reference the nojQuery and jQuery versions separately, for example if you run in a Sybase hybrid container.

● If you do not use makit charts, you can delete the complete makit folder in /resources/sap. The same applies to the sap.me control library.

● If you use the sap-ui-core.js file for bootstrap, you can delete the jquery and jqueryui folders in /resources/sap/ui/thirdparty. These files may be needed when you use the sap-ui-core-nojQuery.js script, but if you have another copy of jQuery available you can still delete the folder.

● Depending on the theme you use, you can delete the base and either the sap_bluecrystal or the sap_mvi folders in each of the /resources/sap/* ... */themes folders.

NoteFor all JavaScript files, an optimized version and a debug (dbg) version exists. If you delete the files, make sure that you always delete both versions. If you can do without easy debugging and want to achieve a minimum installation size instead, you can delete all *-dbg.js files.

You can delete further files, but the size reduction is limited and to find out the files that are not required gets increasingly difficult.

You can also add additional control libraries such as the sap.viz chart library by copying the respective folder from the sapui5-static.zip file.

Device Ready Event

The hybrid web container needs some time for initialization. During this time, the sending of AJAX requests is blocked, meaning that JavaScript code stops once an AJAX request is sent and the code execution stops as well. This leads to a UI freeze effect.

The oData model in SAPUI5 uses AJAX requests internally and the oData model initialization must therefore be done after the hybrid container is ready to avoid a user interface freeze. After initialization, the hybrid web containers fires an event, which is called deviceready in PhoneGap. To fix this issue, move the code where the oData model is created and set the core object or any other controls' model property to the deviceready event listener.

Example:

<script><!-- put the following code in the beginning of the application code -->

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 263

function appReady(){ sap.ui.getCore().setModel(new sap.ui.model.odata.ODataModel(<ODATA_URL>, false));}<!-- bind to the deviceready event -->document.addEventListener("deviceready", appReady, false);</script>

Cross Domain Restrictions

If you load data from an external server or service using AJAX, the external domain has to be configured inside the hybrid web container to make the AJAX request go through the cross domain restriction. The following findings result from an integration of the SAPUI5 demo applications into PhoneGap:

● AndroidIf the AJAX code runs inside the webview in Android, no cross domain restriction exists. This means that you can load data using AJAX from everywhere. The PhoneGap documentation, however, still says that the domain needs to be configured in one XML file.

● iOSThe restriction in webview in iOS still exists and you need to add the domain that is visited using AJAX to a white list file to bypass the restriction. For detailed information about the white list file, see the PhoneGap documentation on the PhoneGap website.

1.1.3.19.9 Using Images in Mobile Applications

When using images in mobile applications, note the following.

Supporting Different Pixel Densities

Some mobile devices, starting with iPhone4 and iPad3, have a display with a very high density of pixels (four pixels where older models would only have one pixel). They are called "retina displays" by Apple to suggest they are as crispand clear as the eye can see. They use four physical pixels to display one logical CSS pixel, so images can be displayed much sharper when given twice as large as usually required because internally the device can use much more pixels to display all details of the image. Browsers on those displays do this automatically when images are scaled down.

So some devices support higher resolution images while others do not. We therefore recommend that SAPUI5 application developers provide image resources for all relevant densities to provide a very crisp and clear display of images on devices with "retina display".

The sap.m.Image control automatically chooses the right density, depending on the device on which it is displayed. If an image of a certain density is not available, the image control falls back to a default image, which should be provided as well.

264 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteThe image control is also used implicitly by other mobile controls, for example

● Button● Segmented Button● Standard List Item

CautionIf you do not have higher resolution images you should set the densityAware property to false to avoid unnecessary roundtrips.

Example

Assume the following controls are displayed on a device with high-density screen (window.devicePixelRatio is 2):

new sap.m.Image({ densityAware: false, // tell the image control that there are no different optimized image variants src : "first.png" // therefore Image control will directly load first.png })

new sap.m.Image({ src : "second.png" // Image control will first look for [email protected], then fall back to second.png})

The first image control has been told that there are no image files for the different densities, so it will directly load "first.png". This image looks as good as other images on retina displays.

The second image control will first attempt to load [email protected] which should be twice as large as the normal image and would be scaled down for display, so it looks absolutely crisp on retina displays. If this file does not exist, it will fall back to "second.png", but this fallback will cause an additional server request.

Naming Conventions

Density related images are loaded if you provide an image name with density awareness in following format is provided:

[imageName]@[densityValue].[extension]

Currently, we support the densities 1.5 and 2. The follwing example shows a set of images with different densities:

● detail.png (default)● [email protected][email protected]

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 265

[email protected] (not supported any more, will use the standard image for such low density device)

Using Icon Font in SAPUI5

The sap-icon:// protocol supports the use of icons in your application based on the icon font concept, which an embedded font instead of a pixel image. Compared to image-based icons, icon font is easily scalable and you can change the color and apply various effects via CSS. SAPUI5 provides the sap.ui.core.icon control and a set of predefined icons is available in sap.ui.core.IconPool.

Using Custom Icons

To use your own icon font files in the sap.ui.core.Icon control, the font file needs to be declared with font-face tag in the CSS styles and the icon font file needs to be registered in sap.ui.core.IconPool. The required icon font file depends on the browser supported by your application. For Internet Explorer (IE) versions below IE9, the font files need the following extensions: .eot and .ttf. For other browser versions, only the .ttf extension is required.

To add custom icons, proceed as follows:

1. Declare the font-face tag in your CSS.Example for IE versions below IE9:

<style>font-face { font-family: 'SAP-icons'; /*Please replace 'SAP-icons' with your font name which will be used when register in sap.ui.core.IconPool*/ src: url('_PATH_TO_EOT_FILE_'); src: url('_PATH_TO_EOT_FILE_?#iefix') format('embedded-opentype'), /*?#iefix is required to be added to the end of the path of eot file here*/ url('_PATH_TO_TTF_FILE_') format('truetype'); font-weight: normal; font-style: normal;};</style>

Example for IE versions as of IE9:

<style>@font-face { font-family: 'SAP-icons'; /*Please replace 'SAP-icons' with your font name which will be used when register in sap.ui.core.IconPool*/ src: url('_PATH_TO_TTF_FILE_') format('truetype'); font-weight: normal; font-style: normal;};</style>

2. Call sap.ui.core.IconPool.addIcon with the following parameters for each character your icon supports:

266 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

○ iconName: This parameter defines the name of the current icon. The icon name is used together with the collection name as an identifier for the icon to address the icon via URI and must, thus, be unique within the collection.

○ collectionName: This parameter defines the name of an icon collection. Together with the icon name it is used to uniquely identify an icon in a URI.

○ fontFamily: This parameter matches the string you have used in the @font-face tag in CSS for the font-family property ('SAP-icons' in the code snippet in step 1).

○ content: This parameter defines the special character that represents this icon; use a format like 'e000' without escape character.

Referencing Icons

To reference icons, you assign the icon URI to a control by setting sURI for the control's corresponding property. To get the icon URI, the following two options exist:

● Call sap.ui.core.IconPool.getIconURI with the iconName property:

jQuery.sap.require("sap.ui.core.IconPool");var sURI = sap.ui.core.IconPool.getIconURI("accidental-leave");//please change the parameter to the name of your desired icon

● If you know the collection name and the icon name, write the icon URI directly in the following format:

sap-icon://[collection-name]/[icon-name]

NoteYou need the collection name only for custom icons. The URI for predefined icons does not need the collection name.

Using Icons in Controls

The following code snippet shows how the sap.m.Dialog control that already supported image URI has been adapted to also support icon URI. sap.ui.core.IconPool.createControlByURI returns an instance of sap.ui.core.Icon if sURI is an icon URI. Otherwise, the second parameter is called as a constructor method to create an instance. The sURI is set for the src property of the instance.

sap.m.Dialog.prototype.setIcon = function(sURI){ this.setProperty("icon", sURI, true); if(!jQuery.os.ios){ //icon is only shown in non iOS platform if(this._iconImage){ this._iconImage.setSrc(sURI); }else{ this._iconImage = sap.ui.core.IconPool.createControlByURI({ src: sURI //src is mandatory /* other properties can be put here, such as id, ...*/ }, sap.m.Image); } }

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 267

return this;};

If the img tag is rendered directly in the control, and not by creating an image control, use the writeIcon method on sap.ui.core.RenderManager. The writeIcon method accepts an URI as the first parameter. Depending on this parameter, it renders either an img or a span tag. The classes and attributes defined in the second and third parameter are also added to the rendered tag.

Font face is inserted into the style sheet dynamically when Icon or writeIcon are used for the first time. If the special character needs to be written into the CSS to show the icon in a control, call the sap.ui.core.IconPool.insertFontFaceStyle function to insert the built in font face in your CSS. This is shown in the following code snippet:

jQuery.sap.require("sap.ui.core.IconPool");sap.ui.core.IconPool.insertFontFaceStyle();

Styling the Icon Control

If you render the icon span directly in your control, or use icon font in your CSS, you have the maximal freedom to style the Icon control.

If you use the icon by creating an instance of sap.ui.core.Icon within your control, however, use the CSS class sapUiIcon to add a new style to the icon. To avoid influencing the style of icons used elsewhere, wrap the icon CSS class with your control's root DOM class.

1.1.3.19.10 Message Handling

The following guidelines for message handling are recommended. We recommend to invest care and energy in good message content:

● Provide short and crisp error messages to the user.● A message should always contain a 'Call for Action'.● To achieve the above you need to map error messages from a backend system.● Focus on the most common error situations and improve the messages there.● For the rest simply state that a 'Backend' or 'Database' error has occurred. The user cannot handle this

anyway and no further details are required. If technically feasible, ease the process of receiving support from IT, for example submit the issue and related information to support or at least provide contact information.

● It is a must to detect all problems related to network connectivity and indicate them as such.

Messages Related to a Page

For showing messages to the user that are related to the currrent page you have two options depending on the importance of the message.

268 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Message Dialog:

● A message dialog interrupts the user's workflow by blocking the current page and needs to be closed by the user.

● Use a message dialog if the message is important and must be acknowledged by the user.● The easiest way of showing a message dialog is to use the sap.m.MessageBox.● If you want full control of the content you can also use sap.m.Dialog control and set the type to

sap.m.DialogType.Message.● On iOS, a special visual design is applied to the dialog. On Android and Blackberry, the message dialog has the

same design as the standard dialog.

Message Toast:

● A message toast is an overlay that disappears after some time or if the user taps somewhere else. It does not block the user.

● Use this pattern if the message is less important and the user should not be blocked in his work.● You can open a message toast easily with sap.m.MessageToast.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 269

Messages Related to Elements of a Page

For showing messages to the user that are related to a specific element of a page there is no dedicated UI control available in sap.m in this version. We recommend to use the sap.ui.core.HTML control to show these error messages 'somewhere close to the input' or use some kind of overlay. Consider that the user will have the on screen keyboard open which might hide messages. Putting the message above an input field could help.

You can set the ValueState of the sap.m.Input control to 'Error' to indicate that the content is not correct.

Multiple Messages

SAPUI5 Mobile does not support multiple messages at the same time. Mobile Designs recommend to be 'more sparse' with messages, that is, only show one message at a time. This can also be achieved by combining and reducing multiple messages.

270 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.19.11 Navigation Using Browser History

HTML 5 offers features, such as HTML pages that fetch data asynchronously and update the UI dynamically without reloading the page. However, the browser history back/forward buttons do not work any more because the URL of the application always stays the same.

This may be acceptable as a back button can be provided directly in the App which can be used instead of browser's back button. For some mobile platforms, however, such as Android, the user is used to using the physical back button to do back navigation inside an application. Thus, the back in the application is no option of choice for SAPUI5 Mobile.

What does the physical back button do?

If an application runs on a mobile device with a physical back button, tapping on the back button has the same effect as tapping on the browser back button. If no history state in browser history exists, it quits the browser application. This is also valid when application runs in a WebView using a hybrid container as long as the container does not interfere with the default behavior of the back button.

How should we support the physical back button?

An applications built with SAPUI5 Mobile runs through pages. After navigating to a new page, the user expects to go back to the previous page when tapping on the physical back button. This behavior assumption requires the following:

● Forward navigation to a new page must add a browser history state.● Back navigation to a previous page must ne triggered using the browser history.

With tje jQuery plugin jQuery.sap.history.js, a new history state can be added by changing the hash of the current URL with serialized state data which is sufficient to restore the current state when doing back navigation. jQuery.sap.history.js also provides an API for navigating back one or several steps through the browser history states.

For forward navigation (also called "to" navigation) and backward navigation (also called "back" navigation), two ways of triggering exist:

● "TO" navigation

○ triggered by controls, for example, tapping on a button to navigate to a new page○ triggered by browser history, that is, tapping on the browser forward button

● "Back" navigation

○ triggered by controls, for example, tapping on the back button in a page's header to go back to previous page

○ triggered by browser history, that is, tapping on the browser back button or the physical back button

The image below illustrates how the four options for trigger handling:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 271

The following sections describe the four options:

"TO" triggered by controls

When "TO" navigation is triggered by controls, a new history state needs to be added to the browser history with the new page information. Later, when doing a back navigation, a history state is popped out from browser history and we can decide which page we go back to by checking the information saved with the history state.

"TO" triggered by browser history

"TO" navigation can also be triggered by tapping on the browser forward button. We don't need to add a new history state because the history state has been added to browser history already. By checking the saved information with this history state, we know which page we go forward to.

"BACK" triggered by controls

In order to support the physical back button, we are required to do every back navigation through the browser history. Thus when back navigation is triggered by a control, we ask the browser history to go back one or several steps by calling the provided API in jQuery.sap.history.js. The following behaviors are the same as Back triggered by browser history.

272 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

"BACK" triggered by browser history

When back navigation is triggered by browser history either the browser back button or the physical back button on mobile device is tapped, a history state is popped out from browser history. By checking the saved information with history state, we can navigate to the specified page.

1.1.3.19.12 Mobile Events

The following is the same for mobile events and Desktop events:

● When running on mobile or touch devices, the application has still the possibility to access to all native browser events, including the touch-related ones.

● Handling of control events fired by SAPUI5 is also the same as on desktop PCs.● When implementing SAPUI5 controls, some browser events can be handled very easily by implementing a

method named on<eventName>, so all the bind/unbind effort is avoided. This is equally possible on mobile.

Basically the whole concept of events is identical.

Additional Events for Mobile Applications

The difference between mobile and desktop events is that on mobile devices additional events are available within control implementations. They are introduced in the following sections.

Additional Mobile Browser Events

On touch-enabled platforms the following events are also provided within UI5 controls to be handled in on<eventName> methods:

● touchstart● touchend● touchmove● touchcancel

Additional Mobile Pseudo Events

jQuery mobile event handling is used in SAPUI5 when running on touch-enabled devices. From the basic browser events it creates semantically richer events. Some of them are also provided automatically in SAPUI5 controls:

● swipe

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 273

● tap● swipeleft● swiperight● scrollstart● scrollstop

For more information, see the jQuery mobile documentation.

Simulation of touch events on non-touch platforms

For testing or demonstration purposes, the events listed above can also be simulated on non-touch devices. When this simulation is enabled, the touch events will also be triggered by mouse interaction.

NoteDue to technical constraints the simulation cannot be perfect, so it may not be used in productive code.

To enable the simulation mode, set the SAPUI5 configuration parameter xx-test-mobile to 'true', for example by appending the URL parameter sap-ui-xx-test-mobile=true.

Events also available in Desktop Apps

This section lists all events that are available in control implementations in all SAPUI5 applications:

Browser Events

● click● dblclick● focusin● focusout● keydown● keypress● keyup● mousedown● mouseout● mouseover● mouseup● select● selectstart● dragstart

274 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● dragenter● dragover● dragleave● dragend● drop● paste

Pseudo Events

The "pseudo events" can be used in on<eventName> methods inside controls like browser events, but are created by SAPUI5 and typically have enriched semantics:

For the detailed meaning of each event, see

● sapdown● sapdownmodifiers● sapshow● sapup● sapupmodifiers● saphide● sapleft● sapleftmodifiers● sapright● saprightmodifiers● saphome● saphomemodifiers● saptop● sapend● sapendmodifiers● sapbottom● sappageup● sappageupmodifiers● sappagedown● sappagedownmodifiers● sapselect● sapselectmodifiers● sapspace● sapspacemodifiers● sapenter● sapentermodifiers● sapexpand● sapbackspace● sapbackspacemodifiers● sapdelete

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 275

● sapdeletemodifiers● sapexpandmodifiers● sapcollapse● sapcollapsemodifiers● sapcollapseall● sapescape● saptabnext● saptabprevious● sapskipforward● sapskipback● sapprevious● sappreviousmodifiers● sapnext● sapnextmodifiers● sapdecrease● sapdecreasemodifiers● sapincrease● sapincreasemodifiers● sapdelayeddoubleclick

1.1.3.19.13 Styling and Theming Mobile Controls

CSS is used in mobile applications to provide the visuals of controls, just like for Desktop controls. The main differences are:

● The mobile browsers supported by SAPUI5 are all based on Webkit. This allows using advanced CSS3 features which are not available in all supported desktop browsers.

● "em" and "rem" should be used for dimensions.

Using LESS Features like Theme Parameters

When controls are created with Eclipse tool support, the CSS files are processed by the "LESS" Open Source CSS preprocessor. Just like in desktop control CSS files, LESS features, in particular variables or "theme parameters", can be used.

1.1.3.19.14 Building Charts with MAKit

The MAKit Chart is a SAPUI5 control that provides charting features. MAKit chart is designed for mobile and tablet use. It has unique features such as Value Bubble and Range Selector that make chart report much more rich and interactive.

276 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

MAKit chart supports the following touch interactions on mobile devices:

● tap to highlight certain part of the chart● double tap● two finger pince to zoom in or out● one finger drag to move chart's Value Bubble highlight● two finger swipe to scroll the chart when zoomed in

Currently, it supports the following chart types:

● Column● Horizontal Bar (Table Bar)● Line● Bubble● Pie● Donut

The value bubble provides an interactive way of showing details of the chart. It provides detailed information, that is, the value of the highlighted chart region. A user can hide or show specific series of the chart by toggling the legends on the value bubble.

The range selector provides an overview of the whole chart to the user and also allows to zoom in or out to a specific part of the chart.

The following controls and elements are provided in the sap.makit library:

● sap.makit/Chart – SAPUI5 chart control (type: sap.ui.core/Control)● sap.makit/Axis – Base type for the chart’s axis (type: sap.ui.core/Element)

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 277

● sap.makit/CategoryAxis – Properties of the chart’s category axis (type: sap.makit/Axis)● sap.makit/ValueAxis – Properties of the chart’s category axis (type: sap.makit/Axis)● sap.makit/Category– Properties of the chart’s category axis (type: sap.makit/Element)● sap.makit/Value – Properties of the chart’s value axis (type: sap.makit/ Element)● sap.makit/Series – Properties of the chart’s series (type: sap.ui.core/Element)● sap.makit/Row – Row collection for data binding (type: sap.ui.core/Element)● sap.makit/Column – Column mapping for data binding (type: sap.ui.core/Element)● sap.makit/ValueBubble – Properties for the chart’s value bubble (type: sap.ui.core/Element)

Simple Types:

● sap.makit/ChartType – Enumeration for chart type (type: string)● sap.makit/SortOrder – Enumeration for category’s sortOrder (type: string)● sap.makit/LegendPosition – Enumeration for legendPosition (type: string)● sap.makit/ValueBubbleStyle – Enumeration for the value bubble’s positioning style (type: string) for

non-Pie/donut/HBar chart● sap.makit/ValueBubblePosition – Enumeration for the value bubble’s position on pie/donut Chart

(type: string)

1.1.3.20 Testing SAPUI5 Applications in Eclipse

You have different options to test your applications locally in Eclipse.

You have created a SAPUI5 application using the SAPUI5 application development tools, see Developing Applications Using SAPUI5 Tools.

1. To use SAPUI5 application preview, see Test in SAPUI5 Application Preview2. To use a Java Web Server, see Test Your SAPUI5 Application on a Java Web Server [page 279]

If you have created a SAPUI5 application for a mobile target device, the application can only run in a WebKit-based browser. You can, however, use the mentioned options for testing your application locally in Eclipse and copy and paste the URL into a WebKit-based browser.

If your application has to access resources on a back-end system (OData), you must enable the back-end access for local testing.

1.1.3.20.1 Test in SAPUI5 Application Preview

You access the SAPUI5 application preview using the Web App Preview, provided with the embedded Jetty server. You can quickly check on your application and open it in the default browser.

NoteJetty provides an internal web preview used in the SAPUI5 application preview. As of the Juno release of Eclipse, this features needs to be installed explicitely.

278 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1. To test the new application with the application preview in an embedded Jetty server, right-click the HTML file or the project node and choose Run As Web App Preview . Everything is configured automatically.

2. To refresh after having changed a file of your SAPUI5 application, choose Refresh on the left hand side of the preview editor to refresh the SAPUI5 preview.

3. To check the files of your SAPUI5 application project in an external browser, choose Open in external browser on the right hand side of the preview editor. This function opens the external browser which is specified in the Eclipse preferences under General Web Browser . This is usually the default browser of your PC. For other external browsers, you can also copy the URL from the text field of the editor to the external browser.

Open in External Browser

1.1.3.20.2 Test Your SAPUI5 Application on a Java Web Server

To test the application in a Java Web Server environment, ensure that the corresponding Server Adapter Eclipse Plugin is installed.

To test the new application, right click the new project and choose Run As ... Run on Server . Select a server (for example, Apache Tomcat), and choose Finish.

Related Information

Set up Tomcat to test SAPUI5 applications [page 280]To test on a Java web server, you can install an Apache Tomcat.

Use a SimpleProxyServlet for Testing to Avoid Cross-domain Requests [page 280]If you are testing locally in your Java Eclipse environment and you want to access an OData service in the ABAP system, a proxy is needed to ensure the same origin policy. In an SAPUI5 application project you can use a SimpleProxyServlet for local testing.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 279

Set up Tomcat to test SAPUI5 applications

To test on a Java web server, you can install an Apache Tomcat.

The recommended versions of Tomcat are 6.0 or higher.

1. Download Tomcat from the respective web site. You can either install the Windows Service Installer, or download and unzip the zip file (you can find the startup script in the bin folder).

2. To deploy your application, choose one of the following options:

○ Without EclipseTo deploy SAPUI5 on Tomcat without Eclipse, you can set up a Tomcat user with manager privileges (see the Tomcat documentation) and use the tomcat manager application for deployment. We recommend, however, to just move your war file into the webapps folder inside the tomcat directory. Tomcat takes care of the deployment, but a restart may be necessary.If you run Tomcat without Eclipse, set the environment variable JAVA_HOME to JDK6

○ In EclipseTo run web applications in Eclipse, you need to register the Tomcat web server.

1. Open the Java EE perspective in Eclipse.2. Open the Servers view, for example by pressing CTRL + 3 and then entering Servers.

3. To open the New Server wizard, choose New Server from the context menu.

4. Choose Apache Tomcat 7.0 and add a new server runtime by pointing to the folder in which you have unzipped the Tomcat installation files. Finish the wizard. You should now see Tomcat v7.0 server in the Servers view.

5. Open the configuration overview by double clicking the Tomcat v7.0 server in the Servers view. Select the Serve modules without publishing server option.

Use a SimpleProxyServlet for Testing to Avoid Cross-domain Requests

If you are testing locally in your Java Eclipse environment and you want to access an OData service in the ABAP system, a proxy is needed to ensure the same origin policy. In an SAPUI5 application project you can use a SimpleProxyServlet for local testing.

CautionBe aware that due to security reasons the SimpleProxyServlet is restricted to local testing purposes only. It can only be used for local host scenarios (accessing Gateway services to avoid cross-domain issues) and will not work when deployed on an application server. For productive use, refer to a mature proxy servlet.

NoteIf you have issues with accessing HTTPS systems via the ResourceServlet or the SimpleProxyServlet it may be necessary to import the root certificate into the Java keystore.

.

Ideally, all OData service URLs should be in one file to make the exchange easier - either in the index.html, or in one separate .js file which needs to be included. The application is responsible for exchanging the URLs before

280 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

checking in and after checking out to SAPUI5 Repository. You can also use the helper function getServiceUrl for which also the application is responsible. See the following example:

#!java<script>//var serviceUrl = "/mypath/myservice"; //url when running on the ABAP system//var serviceUrl = "proxy/mypath/myservice"; //url when running locally in Eclipsevar serviceUrl = getServiceUrl("/mypath/myservice");function getServiceUrl(sServiceUrl) { //for local testing prefix with proxy //if you and your team use a special host name or IP like 127.0.0.1 for localhost please adapt the if statement below if (window.location.hostname == "localhost") { return "proxy" + sServiceUrl; } else { return sServiceUrl; }}</script>

As parameter for the getServiceUrl helper method, use the URL of the OData service document without {protocol}://{host name}:{port number}, for example: /mypath/myservice.

NotePlace the script tag before the script that calls the view (sap.ui.view).

Intranet Servers

The SimpleProxyServlet allows proxy requests to an arbitrary server in the intranet.

The proxy URL that is used in the coding looks like this: proxy/<service url>.

Open the web.xml file located in the <WebContent folder name>/WEB-INF folder and configure the parameter com.sap.ui5.proxy.REMOTE_LOCATION of the SimpleProxyServlet where the placeholders {protocol}, {host name}, {port number} are to be exchanged by the real protocol, host name and port number:

#!xml

<servlet> <servlet-name>SimpleProxyServlet</servlet-name> <servlet-class>com.sap.ui5.proxy.SimpleProxyServlet</servlet-class> </servlet>

<servlet-mapping> <servlet-name>SimpleProxyServlet</servlet-name> <url-pattern>/proxy/*</url-pattern> </servlet-mapping>

<context-param> <param-name>com.sap.ui5.proxy.REMOTE_LOCATION</param-name> <param-value>{protocol}://{host name}:{port number}</param-value> </context-param>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 281

Internet Servers

The SimpleProxyServlet can be configured for proxy requests to internet servers in the same way as for intranet servers. Additional proxy settings may be necessary.

As the SimpleProxyServlet automatically uses the proxy settings from your Eclipse this can be configured in Eclipse under Window Preferences , and select General Network Connections . Here you can specify the proxy entries and the proxy bypass.

For example, set Active Provider to Manual, Schema=HTTP, Host=proxy, Port=8080 under proxy entries and localhost, *.sap.corp as Host under proxy bypass.

Simple Proxy Servlet - Restriction Regarding DELETE Requests

The simple proxy servlet currently does not support the sending of HTTP DELETE requests with content. This is due to restrictions of the Java SE functionality that is used. If an HTTP DELETE request with content is sent, an HTTP 500 result status is sent with the description: "The HttpUrlConnection used by the SimpleProxyServlet doesn't allow to send content with the HTTP method DELETE. Due to spec having content for DELETE methods is possible but the default implementation of the HttpUrlConnection doesn't allow this!"

For practical purposes, this restriction should have only minor effects. This is because:

● When applying a REST-like programming style, an HTTP DELETE request would use the URL to transmit which objects should be deleted, but not the content.

● When building your own protocol that uses the content of the HTTP request, you typically use HTTP POST.

1.1.3.21 UI development toolkit for HTML5 Test Suite

The test suite is an integral part of the UI development toolkit for HTML5 (SAPUI5) core library and is, thus, automatically available for applications using SAPUI5. To start the test suite, add the URL path 'resources/testsuite' to your application URL, for instance http://localhost:8080/demokit/resources/testsuite for the 'demokit' application.

Content of the Test Suite

The test suite provides functionality related to inspecting and trying all aspects of SAPUI5 controls. It consists of the following screen areas:

● Test pages tree on the left top screen area: Different test pages for controls etc. can be selected here.● Preview area on the center top screen area: The page selected in the test pages tree is rendered here and can

be used and tested.● Control tree on the right top screen area: The hierarchy of the development toolkit controls is displayed here;

you can select controls in the tree, which will then be highlighted in the preview area.

282 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● Property sheet on the right bottom screen area: Once you have selected a control in the test pages tree, its properties are displayed on the property sheet and can also be modified. Choose Apply Changes after modifying.

● Event log on the center bottom screen area: Trace output as well as all control events are displayed here.● Settings preview on the left bottom screen area: Here you can adjust how the page is rendered. You can, for

example, select one of the themes delivered with SAPUI5, or enter the name of a theme, which you created.

1.1.3.21.1 Using the SAPUI5 DiscoveryServlet to Automatically Find Test Cases

SAPUI5 automatically detects test cases for controls by means of the DiscoveryServlet. To use this service, the application must configure the servlet in its web.xml as follows:

#!xml<!-- ============================================================= -->

<!-- SAPUI5 discovery servlet used to find available UI test cases -->

<!-- ============================================================= -->

<servlet> <display-name>DiscoveryServlet</display-name> <servlet-name>DiscoveryServlet</servlet-name> <servlet-class>com.sap.ui5.discovery.DiscoveryServlet</servlet-class> <load-on-startup>1</load-on-startup></servlet>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 283

<servlet-mapping> <servlet-name>DiscoveryServlet</servlet-name> <url-pattern>/discovery/*</url-pattern></servlet-mapping>

The servlet discovers all HTML files located inside the test-resources/<ui-library-name> folder of the web application and all resources inside the modules (JAR files) where the location is META-INF/test-resources/<ui-library-name>.

1.1.3.22 Localized Texts

The framework concepts for text localization in SAPUI5 are aligned with the general concepts of the Java platform. The main components of the concept are:

● Identifying languages/locales, see Identifying the Language Code/Locale● Storing and accessing texts in multiple languages (resource bundles), see Resource Bundles● Using localized texts in the application, see Use of Localized Texts in Applications

1.1.3.22.1 Identifying the Language Code / Locale

For the identification of languages, the framework uses a language code of type string. Currently, SAPUI5 accepts the following two syntax forms:

● The Java Locale syntax that combines a lower case ISO 639 alpha-2 or alpha-3 language code with an ISO 3166 alpha-2 country code. Both codes are combined with an underscore. An arbitrary sequence of variant identifiers (also separated by underscores) can be appended as a third component.Example: en_US, zh_TN_Traditional

● Language codes according to the defacto standard BCP 47 (see IETF BCP-47). Most modern browsers use these codes for language identification. As of JDK 1.7 the Java locale class supports them as well.Example: bs-Cyrl-BA, i-klingon

Current Language Code / Locale

SAPUI5 has the notion of a current language. It is determined from the following sources of information. The sources are ordered increasingly by priority and the last available user language/locale wins:

1. Hard-coded UI5 default locale ('en')2. Potentially configured user language (window.navigator.userLanguage)3. Potentially configured browser language (window.navigator.browserLanguage)4. General language information from the browser (window.navigator.language)5. Locale configured in the application coding (jsdoc:symbols/sap.ui.core.Configuration)6. Locale configured via URL parameters

284 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

You use the configuration API to retrieve the resulting current language as follows:

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

NoteThe syntax of the returned value depends on the syntax used for configuration. If the information source is one of the browser language properties, the returned language most likely is in BCP-47 format. If it is configured as a URL parameter, the user might have choosen the JDK Locale syntax.

NoteIn the Internet Explorer (IE), none of the window.navigator.* properties reflects the settings of the Language Preference dialog in IE. Instead, IE returns the language of the OS installation as browserLanguage and the language from the OS regional settings as userLanguage. As a result, the settings in the Language Preference dialog cannot be taken into account for the current language of SAPUI5. This is often confusing for developers and a known shortcoming in IE. The only way to circumvent this is an additional server request where IE provides the corresponding setting in theAccept-Language header. As this technique requires a backend component and SAPUI5 must be able to run without any server component, such a request is not implemented yet.

1.1.3.22.2 Resource Bundles

Resource bundles are a collection of *.properties files. All files are named with the same base name (prefix identifying the resource bundle), an optional suffix that identifies the language contained in each file, and the fixed .properties extension. The language suffixes are formed according to the older JDK locale syntax. By convention, a file without a language suffix should exist and contain the raw untranslated texts in the developer's language. This file is used if no more suitable language can be found.

A resource bundle file is a Java properties file (as described in the Javadoc of class java.util.Properties). It contains key/value pairs where the values are the language-dependent texts and the keys are language independent and used by the application to identify and access the corresponding values.

When a localized text is needed, the application uses the SAPUI5 APIs to load the properties file that matches the current language best. The same applies to any other localized data that can be represented as a string, for example, a date formatter string. To retrieve a text from the properties file, the application uses the (language-independent) key. If no text can be found for this key, the next best matching file is loaded and checked for the text. Finally, if no file matches, the raw file is loaded and checked.

The resource bundle sap.ui.commons.message_bundle consists of the following individual files:

● sap.ui.commons.message_bundle.properties: Contains the raw texts form the developer, determines the set of keys

● sap.ui.commons.message_bundle_en.properties: Contains English texts (without a specifc country)● sap.ui.commons.message_bundle_en_US.properties: Contains texts in American English● sap.ui.commons.message_bundle_en_UK.properties: Contains texts in British English

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 285

1.1.3.22.3 Use of Localized Texts in Applications

SAPUI5 provides the following options to use localized texts in applications:

● Using the jQuery.sap.resources module● Using data binding

Using jQuery.sap.resources

You can use the JavaScript module jQuery.sap.resources to access localized texts. The module contains APIs to load a resource bundle file from a given URL and for a given locale.

To make sure that the jQuery.sap.resources module is loaded, you have to require it as follows:

jQuery.sap.require("jquery.sap.resources");

You can then use the jQuery.sap.resources function to load the resource bundle from the given URL, that is, the bundle name, and for a given locale. When no locale is specified, a default locale (en) is used. The following code snippet shows the use of the jQuery.sap.resources function to return a jQuery.sap.util.ResourceBundle:

var oBundle = jQuery.sap.resources({url : sUrl, locale: sLocale});

For more information, see jQuery.sap.resources in the API Reference.

The resource bundle jQuery.sap.util.ResourceBundle provides access to the localized texts that are contained in the resource bundle. You can use the getText method to access the texts in the loaded bundle by means of their key. This is shown in the following code snippet:

var sText = oBundle.getText(sKey);

Localization Test Page

The test suite provides a test page that shows how to use localized texts. This section only provides a short overview how the jQuery.sap.resources module is used there.

For a localized Web page you need the .html page itself and the .properties files of the required languages, in this example English and German.

The resource bundle i18n.properties is the English fallback version, which is the default version.

welcome=Welcome {0}. Please enter a new contact:lastname=Last Name:firstname=First Name:street=Street:zip=ZIP:city=City:

286 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The resource bundle i18n_de.properties contains the texts in German. The following code snippet shows the content of this file:

welcome=Willkommen {0}. Bitte geben Sie einen neuen Kontakt ein:lastname=Nachname:firstname=Vorname:street=Straße:zip=PLZ:city=Ort:

The localization test page uses these texts to display a welcome message and a form to enter the address of a person. The coding of the test page looks as follows:

jQuery.sap.require("jquery.sap.resources");var sLocale = sap.ui.getCore().getConfiguration().getLanguage();var oBundle = jQuery.sap.resources({url : "res/i18n.properties", locale: sLocale});var oMatrixLayout = new sap.ui.commons.layout.MatrixLayout();oMatrixLayout.setLayoutFixed(false);oMatrixLayout.createRow( new sap.ui.commons.TextView({text: oBundle.getText("welcome", ["Administrator"])}) );oMatrixLayout.getRows()[0].getCells()[0].setColSpan(2);oMatrixLayout.createRow( new sap.ui.commons.Label({text: oBundle.getText("lastname")}), new sap.ui.commons.TextField());oMatrixLayout.createRow( new sap.ui.commons.Label({text: oBundle.getText("firstname")}), new sap.ui.commons.TextField());oMatrixLayout.createRow( new sap.ui.commons.Label({text: oBundle.getText("street")}), );oMatrixLayout.createRow( new sap.ui.commons.Label({text: oBundle.getText("zip")}), new sap.ui.commons.TextField());oMatrixLayout.createRow( new sap.ui.commons.Label({text: oBundle.getText("city")}), new sap.ui.commons.TextField());oMatrixLayout.placeAt("userForm");

With regard to localization, the code above defines the following procedure:

1. Require the jQuery.sap.resources module2. Determine the language3. Load the resource bundle4. Access the text using the welcome key and pass the value for the placeholder ({0}) via an array5. Access the text using the lastname key and set it as text for the Label

Data Binding

You can also use data binding to access localized texts. The ResourceModel is a wrapper for resource bundles that exposes the localized texts as a model for data binding. You use the ResourceModel to bind texts for control properties to language dependent resource bundle properties. You can instantiate the ResourceModel either

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 287

with bundleName (name of a resource bundle that equals a SAPUI5 module name within the require/declare concept), or a bundleUrl, which points to a resource bundle. When you use the bundle name, make sure that the file has a .properties suffix. If no locale is defined, the current language is used.

var oModel = new sap.ui.model.resource.ResourceModel({bundleName:"myBundle",bundleLocale:"en"});var oControl = new sap.ui.commons.Button( { id : "myButton", text : "{i18n>MY_BUTTON_TEXT}"});// attach the resource model with the symbolic name "i18n"oControl.setModel(oModel, "i18n");

NoteThe current data binding implementation does not allow to pass parameters to your texts in the resource bundle. If you have to pass parameters, you must do this on your own. You can, however, access the resource bundle directly from the model instead of loading it:

var myBundle = oModel.getResourceBundle()

After the instance has been created, you have a model containing the resource bundle texts as data.

For a complete overview of available methods and parameters, see the API Reference: ResourceModel

1.1.3.23 Translation Guide for SAPUI5 Application Developers

Texts in SAPUI5 applications can be translated in an ABAP system. It is a requirement that the name of the file containing the text elements ends with '.properties' and a special key in the format # SAPUI5 TRANSLATION-KEY <GUID with 32 characters must be provided in the first line. In addition, every text element needs a classification such as the text type.

Before you translate texts, make sure that you are using the SAPUI5 repository to store your UI5 application artifacts, see Synchronizing with the SAPUI5 Repository.

Functional Overview

● The purpose of the text API in the SAPUI5 repository is to enable an ABAP translation process for text elements of SAPUI5 applications developed in Eclipse that are stored in the SAPUI5 repository.

● The text elements are included in a property file (here denoted as a '<name>.properties' file, where '<name>' stands for an identifier).

● The text elements stored in '<name>.properties' files are transferred to an ABAP server.● In addition, these table entries are written to a transport request.● These texts can then be translated in the usual way.● The master language of the SAPUI5 repository is taken as the master language for the submitted text

elements.

288 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● The translated texts can then be accessed during runtime.

1.1.3.23.1 Prerequisites for Translating Text Elements

The '<name>.properties' file must fulfill certain prerequisites for processing:

The table entries for the text elements are written if the following prerequisites are met:

● The file name must end with '.properties'.● The first line in the '<name>.properties' file must contain a certain identifier: # SAPUI5 TRANSLATION-KEY

<GUID with 32 characters>.

CautionThis GUID will serve as a unique identifier for the 'properties' file, therefore it must never be copied to other '<name>.properties' files and it must never be changed in this file. The GUID can be created with the ABAP function module 'GUID_CREATE', or the complete line can be generated with the ABAP report /UI5/TEXT_FILE_GEN_TRANS_KEY. Since this GUID is the only unique identifier, it is possible to relocate or rename the properties file and the text elements in the table will be preserved.

● The file must not contain any duplicate text elements.

Additionally, transport entries are created in the target ABAP system if:

● The corresponding SAPUI5 BSP application is not located in a local package ($TMP).● A valid transport request is already available.

Whenever the property file is relocated, whether to another folder, application, or package, the file must be submitted again to the SAPUI5 repository.

If the BSP application on the ABAP server is reassigned from a local ($TMP) to a non-local package, the file also needs to be resubmitted. All text elements will be generated again with the new creation timestamp.

NoteAs the master language of the SAPUI5 repository serves as the master language of the texts, it is important that the same language is used for the creation of the repository as has previously been used for the property files.

When using the SAPUI5 repository team provider and creating the BSP application manually the correct language has to be chosen on the logon screen.

1.1.3.23.2 Classification of Text Elements

Text elements in the '<name>.properties' file are simple value key pairs separated by an equals sign. However, in order to enable proper translation for these text elements, it is necessary to classify the text elements with additional information. This additional information must be placed in the line directly above the text element and must begin with the number sign ('#').

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 289

The complete line must have one of the following structures:

● #<TextType>● #<TextType>,<MaximumLength>● #<TextType>,<MaximumLength>:<AdditionalContextInformation>● #<TextType>:<AdditionalContextInformation>

1.1.3.23.3 Attributes of Text Elements

Text Type

Each text element must have a text type assignment. Text types can be, for example, XBUT for button texts, XFLD for field labels, or XTXT for general texts. A list of the various possible text types is provided below.

Maximum Field Length

The optional maximum text length information can be provided directly after the text type, separated by a comma.

Additional Context Information

An optional additional comment is provided for the translator, separated by a colon.

1.1.3.23.4 List of Text Types

SAPUI5 short texts:

Text Type Corresponding S2X Type Description

XACT accessibility Accessibility

XALT alternativetext Alternative text

XBCB breadcrumbstep Breadcrumb step

XBLI listitem Bullet list item text

XBUT button Button text

290 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Text Type Corresponding S2X Type Description

XCAP caption Caption

XCEL cell Cell

XCKL checkbox Checkbox

XCOL tableColumnHeading Column header

XCRD tabStrip Tabstrip

XDAT datanavigationtext Data navigation text

XFLD label Label

XFRM frame Frame

XGLS term Term

XGRP grouptitle Group title

XHED heading Heading

XLGD legendtext Legend text

XLNK hyperlink Hyperlink

XLOG logentry Log entry

XLST listbox List box item

XMEN menu Menu header

XMIT menuitem Menu item

XMSG messagetext Message text

XRBL radio Radio button

XRMP roadMapStep Roadmap step

XROW tableRowHeading Table row heading

XSEL selectionText Selection text

XTBS tab Tabstrip text

XTIT tableTitle Table title

XTND treeNode Tree node text

XTOL quickInfo Quick info text

XTXT generaltext General text

SAPUI5 long texts with length of more than 120 characters:

NoteThe total line length of SAPUI5 long texts must not exceed 255 characters.

Text type Corresponding S2X type Description

YACT accessibilitylong Accessibility (long)

YBLI list Bullet list item text

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 291

Text type Corresponding S2X type Description

YDEF definition Definition

YDES description Description

YEXP explanation Explanation

YFAA faqa FAQ answer

YFAQ faq FAQ

YGLS glossarydefinition Glossary definition

YINF instruction Instruction

YLOG logEntrylong Log entry

YMSE errorMessage Error message

YMSG messagetextlong Message text (long)

YMSI informationMessage Information message (long)

YMSW warningMessage Warning message

YTEC technicaltextlong Technical text

YTIC ticker Ticker / marquee

YTXT generaltextlong General text (long)

NOTR No translation

1.1.3.23.5 Example: <name>.properties File

NoteExchange the <GUID> in the first line with a real generated 32-character GUID.

# SAPUI5 TRANSLATION-KEY <GUID>

#XBUT,20

BUTTON_SAVE = Save

#XMSG

MESSAGE_ERROR1 = Error during creation of {0}

#XCAP,20: furniture element

CAPTION_TABLE1 = Table 1

#XFLD: first name in address input dialog

FORMULA_FIRSTNAME = First Name

292 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.3.23.6 Information for Translators

The following information is relevant for translators:

● SAP Note 1686090 must be implemented in the translation system to enable the translation of SAPUI5 text elements. SAPUI5 text elements are treated as ABAP short texts with translation object type: UI5T.

● The translation object name is a GUID, which is the key taken from the original property file containing the text elements (the GUID from the first line) (see under Prerequisites: # SAPUI5 TRANSLATION-KEY <GUID with 32 characters>).

● The text key of each text element consists of the text type and an individual GUID, separated by a space.● The UI5T texts are stored in the following database tables which are stored with a SAP/customer namespace:

○ /UI5/TREP_TEXT: Master table with the text name, unique text GUID, text type, additional context information, and another GUID that is the translation object name (the GUID from the property file).

○ /UI5/TREP_TEXT_T: Language-dependent table containing the original and translated text; the key is the text GUID as in table /UI5/TREP_TEXT and the language key.

○ /UI5/TREP_FILES contains the (translation) object name (the GUID from the property file) and path information for the property file.

1.1.3.23.7 Finding the Where-Used Location of a Text Element

Finding the origin of a text in the source code has to be done manually:

● Use GUID to find the corresponding property file (path information) in table /UI5/TREP_FILES; the GUID corresponds to the field PROP_FILE_GUID.

● The translator sees a key for each text element, which is a concatenation of the text type and another GUID. This GUID corresponds to the field PROP_TEXT_GUID in table /UI5/TREP_TEXT; here you can find the text name for a particular GUID.

● The developer can use this text name to search in the corresponding project in Eclipse to find the location where this particular text is used.

1.1.4 References

1.1.4.1 Compatibility Rules

SAPUI5 plans to be a so-called Release Independent Component (RIC). An important constraint for this is that it must be as simple as possible to upgrade to a newer version. This makes compatibility rules so important.

The following sections explain the meaning of compatibility with regard to the SAPUI5 application and control development. A version flag for the bootstrap indicates to the core to which previous SAPUI5 version the current functionality should be compatible to.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 293

Versioning Scheme

SAPUI5 uses a 3 digit version identifier, for example 1.4.3. The digits have the following meaning:

● The first digit (1) specifies the major version number.● The second digit (4) specifies the minor version number.● The third digit (3) specifies the patch version number.

New releases of SAPUI5 are described by the major and minor version number. The patch version number is only used to identify patches within a release.

API Evolution

If not mentioned differently, in the following paragraphs "API" refers to "public API", meaning functions, classes, namespaces, controls with their declared properties, aggregrations, and so on. The sole definition of the public API is the SAPUI5 Library - Core & Standard Controls (API Reference Documentation, JSDoc), which is available in the Demo Kit. Features that are not mentioned in the SAPUI5 library are not part of the API.

The following rules apply for introducing new APIs or making incompatible changes to existing APIs:

A major release, that is, a release with a new major version can introduce new APIs or make incompatible changes to existing APIs. If this is the case, the incompatibilities are described in the Release Notes.

A minor release, that is, a release with a new minor version can introduce new APIs, but does not contain incompatible changes to APIs, which have been introduced in the same major release.

A patch release, that is, a release with a new patch version, only contain fixes to the existing implementation, but do not introduce new features or incompatible API changes.

NoteExceptions to these rules are possible, but only in very urgent cases, such as security issues. The exceptions are documented in the Release Notes.

Compatible Changes

The following changes to existing APIs are compatible changes:

● Adding new libraries, controls, classes, properties, functions, namespaces to the API● Generalizing properties, that is, moving properties up in the inheritance hierarchy● Changing the logging behavior, that is, adding or removing log output, modifying the content of existing log

output; logging is not part of the API● Adding new values to enumeration types; this means that when dealing with enum properties, always be

prepared to accept new values, for example, by implementing a "default" or "otherwise" path when reacing on enum values

● Modifications to the markup or style (HTML, CSS) of controls

294 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Incompatible Changes

The following changes to existing APIs are incompatible and are only implemented in major releases:

● Removing an API (library, namespace, function, property, control, events, and so on)● Renaming an API (library, namespace, function, property, control, events, and so on)● Removing support for parameters● Removing support for configuration entries● Reducing the visibility of an API; this does not break JavaScript applications, but changes the contract● Removing or reordering parameters in an API signature● Reducing the accepted value range, for example, parameter of a function● Broadening the value range of a return value (or property); exception: Enumerations● Moving JavaScript artifacts (namespaces, functions, classes) between modules● Replacing asserts by precondition checks● Moving properties, etc., down in the inheritance hierarchy● Changing the name of enum values● Changing defaults (properties, function parameters)● Renaming or removing files

If possible, SAPUI5 marks old artifacts as deprecated and creates new artifacts, if applicable, instead of incompatible changes. A deprecation documentation in the SAPUI5 library and maybe a log entry in the implementation explain why and when an artifact has been deprecated and provide hints how to achieve the same results without deprecated functionality.

CautionSome of the new functionality or controls are in an experimental development state and documented as such. These features are still under development and changes to their API are very likely; inthese cases, even incompatible changes in minor releases may occur. They are included in public releases to collect feedback from early adopters. Consumers of such APIs must understand that their respective code might be broken (repeatedly) when upgrading to new SAPUI5 releases and they must be willing to adapt to such changes.

1.1.4.1.1 Third Party Open Source Libraries

SAPUI5 contains and uses several third party open source libraries, for example, jQuery. These libraries can also be used by applications and/or custom control libraries, but the SAPUI5 compatibility policy described within this document does not apply to these third party libraries.

If you want to use the contained third party open source libraries, note the following restrictions:

● SAP decides which version(s) and modules of the used libraries are provided.● SAP can upgrade to higher version(s) of the used libraries even within a micro release.● For important reasons such as security SAPUI5 can stop providing a library.● The third party libraries are provided "as is". Extensions, adaptations, and support are not done by SAP.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 295

NoteFor closed source libraries, a use beyond the use of the corresponding SAPUI5 controls is not allowed.

For a list of the third party open source software used in SAPUI5, see Third Party Open Source Libraries .

1.1.4.1.2 Exceptions: Important to Know

Not part of the public API are all functions, and so on, which are not declared as public in the SAPUI5 library. Also not part of the API is the rendered HTML and the CSS of the controls. This means in particular that the below mentioned scenarios can cause problems, also when switching minor or micro versions. The support for these problems provided by SAP can only be limited, and an adaptation of non-SAPUI5 coding may be necessary. JavaScript facilitates the modification of code that belongs to someone else, for example, enriching prototypes of foreign classes, adding properties or functions to existing objects. This should not be forbidden, but the consequences, meaning the risk of conflicts when SAPUI5 is enhanced, must be clear.

Scenarios:

● Manipulation of HTML/CSS, for example via jQuery, control.addStyleClass, or directly via CSS● Using or overriding non-public functions, etc.● Creation of new controls, for example "Notepad-Controls" based on existing controls (inheritance) or

subclassing in general; new classes also depend on private functionality of the super classes, collision of generated functions for properties, aggregations are possible

● Pixel-perfect compatibility is not guaranteed for SAPUI5 owned controls and, thus, also not guaranteed for controls inheriting from SAPUI5 controls.

1.1.4.2 Naming Conventions for Control and Application Development

The following sections introduce the naming conventions for control and application development for SAPUI5.

1.1.4.2.1 Naming Conventions for Control Artifacts

We recommend to use following naming conventions for control artifacts:

● Start control names with an upper case letter and use camel case for concatenated words, for example MatrixLayout.

● Start control property names with a lower case letter and use camel case for concatenated words, for example colSpan.

● Start control event names with a lower case letter and use camel case for concatenated words, for example: press.

296 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

● Start control method names with a lower case letter and use camel case for concatenated words, for example doSometing.

● Start control aggregation names with a lower case letter and use camel case for concatenated words.● Start control association names with a lower case letter and use camel case for concatenated words.● For control, property, event, and relation names use unique names to avoid name clashes in generated

classes.● Start parameters of control events with a lower case letter.

NoteSAPUI5 tools check and enforce some of these rules.

The generated setter/getter methods for properties as well as the generated methods for events for the aggregations and associations use camel case notation, for example attach<EventName>.

SAPUI5 controls have constructors, which accept a set of properties and events as JSON string. The framework expects that the names used as keys in a JSON string exactly match the case of the defined control properties and events.

If SAPUI5 controls are exposed as tags, the tag name and its attributes should fit the following naming conventions:

● Start tag names with a lower case letter and use camel case for concatenated words. Except for the lower case of the first character, tag names should match the name of the control to create a relation between the tag and the respective control, for example matrixLayout.

● Start tag attributes with a lower case letter and use camel case for concatenated words, for example colSpan● Name tag attributes for event handlers in lower case letters as follows: on<event-name>; for example onpress

1.1.4.2.2 Reserved Characters for Control IDs

The SAPUI5 framework regards the dash '-' as a forbidden character for control IDs. Applications must not use this character in their control IDs.

Control renderers, however, should use the dash to derive synthetic IDs from control IdDs, for example, by appending a suffix like "-mysuffix" to the control ID. By this, naming conflicts with the application can be avoided.

Character Description

- Reserved for separators for synthetic IDs

1.1.4.2.3 Reserved IDs for DOM Nodes and Elements

The following table contains a list of IDs reserved for SAPUI5 core.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 297

ID Description

sap-ui-bootstrap ID of the bootstrap script tag

sap.ui.core-script ID of the bootstrap script tag (deprecated)

sap-ui-* Prefix of the IDs created SAPUI5-internal

*-r Suffix for former UR LightSpeed root areas (similar to UIArea of SAPUI5)

The following table contains a list of IDs currently used in the sap-ui- namespace.

ID Description

sap-ui-library-* Prefix for UI libraries script tags

sap-ui-theme-* Prefix for theme stylesheets link tags

sap-ui-highlightrect ID of the highlight rect for controls in TestSuite

sap-ui-blindlayer-* ID for BlockLayer

sap-ui-static ID of the static area of SAPUI5

sap-ui-TraceWindowRoot ID of the TraceWindowRoot

sap-ui-xmldata ID of the XML Data Island

1.1.4.2.4 Reserved DOM Attributes

The following table contains a list of reserved DOM element attributes names.

Attribute Description

data-sap-ui-* Namespace for custom attributes of SAPUI5

NoteIn general, all custom attibutes should be prefixed with data-.

1.1.4.2.5 Reserved URL Parameters

The following table contains a list of reserved URL parameter names that should be avoided by applications, meaning that an application can use these parameters, but should not introduce its own parameters with these names.

Attribute Description

sap-* Namespace for URL parameters introduced by SAP AG

298 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Attribute Description

sap-ui-* Namespace for URL parameters introduced by SAPUI5

1.1.4.2.6 Control CSS

To avoid collisions, all CSS classes written to the HTML must start with "sap" if developed inside SAP, and with "sapUi" or "sapM" if developed within the SAPUI5 development teams. Outside the respective groups these prefixes should not be used.

For CSS classes for a specific control, add the control name or an abbreviation of the control name to the above mentioned prefix. For controls outside the commons library you may also add the library name between the prefix and the control name, especially if developed outside the core UI5 development teams.

The HTML root element of controls should contain the CSS class name, and all inner HTML elements requiring a class name should use this class name and add a suffix.

All CSS selectors written by SAPUI5 control developers must refer to at least one CSS class. Pure HTML elements should not be styled to avoid affecting non-owned HTML.

Inline CSS should only be used for control instance specific style, such as the button width.

Styling Contexts

If the visuals of controls are different depending on the context or container in which they are used we recommend to use CSS cascades:

● The area or container writes a marker CSS class to the HTML and documents this CSS class in its JSDoc. The documentation should mention the purpose and contract or meaning of this class, for example, that it modifys the appearance of children in a way that better fits table cells, toolbars, or headers.

● The CSS class may have no CSS styles attached. It is a pure marker. This is because such styles would also need to stay stable and might cause trouble for other containers where these styles are not desired.

● The naming convention for these classes is as follows: Suffix -CTX, for example, sapUiTable-CTX or sapMList-CTX or sapUiBorderless-CTX. This makes them easily discernible from "normal" CSS class names.

● Controls that are used to modify their appearance in such an area shall have CSS where this marker class is used in a cascade and provides the suitable style, for example, .sapUiTable-CTX .myCompanyInputField { border: none; }.

1.1.4.3 Typed Views and Controllers

For more complex use cases, a more formal and, thus, more complex way to define views and controllers may be necessary.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 299

The following section describes how you create new classes by using prototype inheritance and how to declare their API.

Typed Controllers

To create a controller that is a new type of its own, you need to write a boilerplate code and declare the functions of the new prototype:

/* boilerplate code for typed Controller */jQuery.sap.declare({modName:"sap.hcm.AddressController", type:"controller"}); // declaring a special type of module sap.hcm.AddressController = function () { // the constructor sap.ui.core.mvc.Controller.apply(this, arguments);};jQuery.sap.require("sap.ui.core.mvc.Controller"); // this is currently required, as the Controller is not loaded by defaultsap.hcm.AddressController.prototype = jQuery.sap.newObject(sap.ui.core.mvc.Controller.prototype); // chain the prototypes/* end of boilerplate code for typed Controller */

// to avoid the above we could in the future offer it behind a simple call to:// sap.ui.defineController("sap.hcm.Address");

sap.hcm.AddressController.prototype.onInit = function() { // modify control tree - this is the regular lifecycle hook

};

// implement an event handler in the Controllersap.hcm.AddressController.prototype.doSomething = function() { alert("Hello World");};

1.1.4.3.1 Support for Unique IDs

Each view and its content usually defines static IDs. You use these IDs to identify and modify the controls within your controller during runtime. If you reuse or nest these views, the IDs are no longer unique. To avoid ambiguity, each view adds its own ID as prefix to all its child controls. This only happens if a static ID is provided. If the ID is created during instantiation of the control, it is unique per default.

If you create further controls during runtime, the controller creates a unique ID by calling the oController.createId("ID") method. These methods add the necessary prefix to the ID.

If you want to modify the control with the ID <ID>, you can call the byId(<ID>) method on your view to get the correct control directly. You do not have to handle all the prefix stuff on your own. The following view defines a button with the static ID abutton (ButtonView):

<core:View viewName="sap.hcm.ButtonView" controllerName="sap.hcm.myController" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml">

300 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

<Button id="aButton" text="Click me"/><core:View>

The following view defines a view embedding the same view several times (ContainerView):

<core:View viewName="sap.hcm.ContainerView" controllerName="sap.hcm.Address" xmlns="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml"> <core:View id="ButtonView1" viewName="sap.hcm.ButtonView"/> <core:View id="ButtonView2" viewName="sap.hcm.ButtonView"/><core:View>

The view is created as follows:

... var oView = sap.ui.view({type:sap.ui.core.mvc.ViewType.XML, id:"myContainerView",viewName:"sap.hcm.ContainerView"});...

The container view has the following IDs:

Both child views IDs have the prefix myContainerView--:

myContainerView--ButtonView1

myContainerView--ButtonView2

To get one of the child views, use the following code:

... var oButtonView1 = oView.byId("ButtonView1");...

The button view has the following IDs:

ButtonView1--aButton

ButtonView2--aButton

To get the button control, use the following code:

... var oButtonView1 = oView.byId("ButtonView1"); oButtonView1.byId("aButton");...

1.1.4.3.2 View Cloning

Another important aspect of SAPUI5 views is their cloning behavior. As you might know, SAPUI5 aggregation bindings can use template control to create a series of similar controls based on a collection of data, for example, items in a RowRepeater for each entry in a model array. The data binding uses a ManagedObject.clone operation to create multiple controls out of a single template. For normal controls, the clone operation is based on the control settings that are decribed by SAPUI5 metadata: properties, aggregations, associations, event handlers and so on. The clone operation collects all these settings and creates a new instance out of it.

For views there is a conflict between this basic, generic approach and the way how views usually define their content: via hooks (JSView) or via persisted XML or JSON files. Furthermore, it is allowed and documented best

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 301

practice to modify the view in the onInit hook of its controller. To avoid conflicts between the generic cloning and the MVC concepts, views implement a slightly modified clone operation: only a subset of the view settings are cloned, the remainder is re-created by calling the hook (JSView) or applying the external view description (XML or JSON file), depending on the view type.

Cloned in a generic way are the following settings:

● any models that have been set (setModel())● registered control event listeners (attachSomeEvent)● registered browser event listeners (attachBrowserEvent)● bindings (bindProperty, bindAggregation)

Not cloned, but recreated are all aggregations, namely the content.

In scenarios where the above clone approach still leads to undesirable behavior, factory functions can be used for the aggregation binding instead.

Related Information

Aggregation Binding [page 101]

1.1.4.4 File Names and Locations (View and Controller)

Controllers and views are defined and instantiated via a name that equals a SAPUI5 module name within the require/declare concept. This means that by default all files have to be located in a subfolder of the resources folder of the Web application. If this location is not appropriate, deviations can be configured as described in the following example:

The following example assumes that your views and controllers are located on your local machine where the SAPUI5 runtime is loaded from another machine. When you instantiate a view or a controller, SAPUI5 runtime loads them in relation to the resources folder of the machine where SAPUI5 runtime was loaded. To inform SAPUI5 runtime that your views and controllers are located on your local machine, use the following code:

jQuery.sap.registerModulePath(sModuleNamePrefix, sURL);

or

sap.ui.localResources(sModuleNamePrefix);

It is usually sufficient to use sap.ui.localResources which internally registers sModuleNamePrefix to the URL "./" + sTransformedModuleNamePrefix, where all dots are replaced by slashes in the transformed name. All files starting with sModuleNamePrefix will then be loaded in relation to the location of the HTML page that called sap.ui.localResources.

If your files are located at http://<localhost:8080>/<myapp>/, for example, you can use registerModulePath as follows:

jQuery.sap.registerModulePath("myapp", "http://<localhost:8080>/<myapp>/");

302 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

or

sap.ui.localResources("myapp");

All views and controllers with a name starting with myapp, for example myapp.MyView, will then be loaded from your local machine.

1.1.4.5 Troubleshooting

The followig sections give guidance on how to deal with issues that may come up when you develop SAPUI5 applications. It is mainly intended for issues on beginner level.

Browsers may behave differently not only with regard to rendering and event handling, but also with regard to the debugging tools they provide. You can start to develop your application in any browser, however, you should double check on a regular basis whether your development also works with other browsers. To start the development tools, for most browser youcan choose F12 on your keyboard. Or you start them from the browser menu.The following list gives you some information about different common browsers:

● Chrome provides excellent built-in debugging capabilities.● Firefox provides built-in developer tools, but we recommend to install the Firebug extension which offers

more functionality.● Internet Explorer provides built-in developer tools. However, these tools are lacking functionality or make

some steps a little more complicated then neccessary. For example, there is an extra button you need to explicitely hit in its developer tools to start debugging, whereas in other browsers you just have to open the tools. Visual Studio provides a description how to use Visual Studio for debugging applications for Internet Explorer with the title Debug Web Apps with Visual Studio.

● Safari provides a native set of developer tools. For remote debugging on mobile devices, see [Link].

1.1.4.5.1 Debugging

The first step in analyzing the issue is debugging. Therefore, you need to know how you can debug in your respective browser.

The development tools of the current browsers allow you to set JavaScript debugging breakpoints. In most browsers, setting the breakpoint is sufficient, but in Internet Explorer, script debugging needs to be turned on explicitely and the selection of the correct file can be tricky when it is loaded using Ajax requests because the file name is not listed. Once you have stopped the script execution, you can inspect and modify the variables. You can now execute the code step-by-step.

NoteChrome has some restrictions with regard to modifying variables.

We recommend to read the basic tutorials on debugging in the different browsers that are available online. For information on browser debugging for ABAP developers, see Browser Debugging for ABAP Developers.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 303

Remote Debugging on Mobile Devices

If you want to make sure that your application is also running on a mobile devices, you can use a simulator, or, as they all have restrictions, we recommend that you debug your application remotely on the target device. This is the only way you can make a reliable statement about the performance of your application on, for example, an iPad. The process varies depending on whether you debug on an Android device or on an Apple device. For more information, see the respective documentation for remote debugging for Android or Apple devices on the respective vendor's websites.

Tips and Tricks for Debugging

The following list provides some useful toips and tricks for debugging SAPUI5:

● If you only see minified sources or scrambled code from SAPUI5 sources instead of the real code behind it, activate the Debug Sources option in your browser. You can enable this option as follows:

○ Add the sap-ui-debug=true parameter to your URL.○ Use the Support Tool to toggle Debug Sources on and off.

● List of useful URL parameters:

Parameter Description

sap-ui-debug Set this parameter to true to activate the Debug Sources option.

sap-ui-language Use this parameter to change the language.

sap-ui-theme Use this parameter to switch themes, for example sap-ui-theme=sap_goldreflectionor sap-ui-theme=sap_bluecrystal.

● Debugging with the support toolYou can use the support tool to get additional information about the SAPUI5 application. It provides a tree structure with all existing controls that can be used to edit properties at runtime, view binding information, and set breakpoints on instance level.For more information, see [Link aufs Support Tool]

1.1.4.5.2 Logging and Tracing

You can use the SAPUI5 logging for debugging purposes, but also use jQuery.sap.log.* or $.sap.log.* functions log in your application code with different security levels:

The following code line issues a log statement with severity level error. The browser highlights this statement in red color and displays it like a JavaScript error:

$.sap.log.error("This should never have happened!");

304 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

This code line issues a log statement with severity level information. The browser does not display this statement if your log console is set to filter for errors only:

$.sap.log.info("FYI: something has happened");

Locating the Logger Output

The developer tools of Internet Explorer, Chrome, and Safari, as well as Firefoxe's Firebug extension offer a console API that you can use for logging. The log output is additionally directed to the console.

Using the Network Trace

If content misses in your application, check the network trace of your page for occurrences of errors like 404 (Page/file not found) or 500 (Internal server errors). This also tells you if an OData request has failed or if resources are not being loaded because of a wrong URL.

To start a network trace, for example, in Chrome, open the developer tools and switch to the Network tab. In the button bar at the bottom of this tab you can start and stop tracing. To see the network requests that are sent from your application, you have to start the trace and then reload the page. Once the loading has finished, you see a list of all requests that were triggered, along with the request status (and highlighting to show errors). Click on a request to view you further details, for example headers that were sent or the response that was retrieved.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 305

1.1.4.5.3 Troubleshooting: Common Issues

The following sections provide information on common issues.

An Empty Page Comes Up

An empty page is most likely caused by a JavaScript error. JavaScript errors stop all subsequent execution.

To solve the issue, check the browser's JavaScript console or the Firefox error console. If they do not indicate that an error has occurred, check if you added the UI controls to an existing element in the page by using placeAt(…). If this is not the cause, check in the browser's DOM inspector whether this "existing element" actually contains child HTML which resembles the controls you have added. Check if the HTML elements are set to be visible and check the dimensions. The height (or width) may have collapsed to zero, thus making the element invisible. This happens, for example, if an HTML element with no height set has a child element with a height set to 100%, as this height refers to the height of the parent element with an undefined height.

Content or Control is not Visible

If content or a control is not visible, check in the DOM inspector of your browser whether the respective HTML exists in the document, or not. You can either search for the control ID or drill down the control hierarchy. It is often the case that the height has collapsed to zero, thus making the element invisible. A possible cause is if you have set no height for an HTML element, but set the height for a child element to 100%. The 100% refer to the height of the parent element with an undefined height, meaning that the child element wants to be as tall as its parent. You can also check whether the control and its parents are set to visible. Or, if you use data binding, check if the elements are properly bound. You can also use the support tool for this check.

Content or Control is set to 100% Height, but Setting Does not Work

Check the height settings of the parent elements. In CSS, a percentage height only works when the parent has a defined height. This issue is often caused by parent elemnt with no height setting or again a percentage height and one ancestor with no defined height. In CSS, this results in a height that is collapsed to the minimum height accomodating all content. Some typical controls, however, adapt their height to the content are the sap.ui.core.View (all types) and the sap.m.Page controls. By setting the View height to any fixed height or setting the View and all ancestors to 100% height, you can define its height and 100%-height children will work fine. And the Page control can be set to enableScrolling: false: when scrolling is allowed, the scroll container in the Page control grows with the content, but when you want to set the content to 100% height scrolling does not make sense because by definition there is no scrolling when the content is as tall as the available space.

306 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Proportions of a Rendered Control Look Odd

Check if the doctype is set correctly in your page. Some controls are not rendered correctly if the doctype is missing or is not correct. Table headers, for example, become exceptionally high.

Style of an Application or a Control Looks Odd

Check if you have used custom styles in your application. If yes, they probably collide with styling in the theming libraries. One approach is to use the browser's debugging tools to inspect the element which has the wrong styling. You can usually see on the HTML tab which styles are applied to a DOM element. If you have styles in the list that your application adds, disable these styles in the debugger to see whether this solves the problem. Note that SAPUI5-specific CSS classes and IDs start with a sapUi prefix, for example, sapUiButton.

If this does not solve the issue, check for inline styles that are be applied to the element in the HTML code. You can also try to isolate the control from the application to see if there is an issue with the control instead of a collision of styles.

If none of the above solves the problem and the issue does not seem to be application specific, open a CSS message.

Console Shows an Error Indicating That Something is Wrong With SAP-UI-CORE.JS, Line 2

Although an issue in SAP-UI-CORE.JS is not impossible, the error often originates elsewhere. To find the actual issue, activate the SAPUI5 debugging sources. This enables you to see in more detail where the message is thrown and it gives you the opportunity to set a breakpoint at the corresponding line. From there, you can dig deeper into the problem and also have a look at the call stack to see where it has started.

1.1.4.5.4 Browser Debugging for ABAP Developers

When you debug code in SAPUI5, keep in mind that you can not debug SAPUI5 in your IDE. If you use Eclipse, for example, a breakpoint set in Eclipse does not stop your script when it is executed in your browser, unless you use the debugger; statement explicitely in your code. The browser does not know about your IDE and does not communicate directly with it. Thus, to debug in SAPUI5, use your browser's debugging tool.

ABAP Debugger vs. Browser Debugger

This section explains how you use the debugging tool of a Chrome browser. Keep in mind that you have to test your application on all browsers that are officially supported by SAP, because the implementation differs

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 307

depending on the browser used, seeChoose your Browser. To start the debugger, use the browser menu or choose F12 (valid for most browsers).

The following explanations assume that your application is up and running on your web server, either a local Tomcat, or a remote server.

In a first step, locate the lines of code you would like to inspect and set breakpoints. The following figure shows an application that is opened in the Chrome debugger. The default tab Elements is opened, and a small bell icon with a number located at the right border of the footer indicates the number of messages from the console.

On the Elements tab, the HTML elements of the DOM are displayed in a tree structure. To see the JavaScript code within the application and to set a breakpoint there, open the Sources tab. From there, you can open any source files that is included. When you open the tools the first time, you ususally have to click the arrow icon on the left hand side of the Sources tab (as indicated in the following figure) to open the sources tree.

308 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

To see the actual content of the HTML page and to set a breakpoint, open the HTML page from the sources tree. This is similar to the ABAP debugger when you execute and debug an application from the workbench. The following figures show the ABAP workbench debugger and the Chrome debugger.

The following figure shows the ABAP workbench debugger. The bubbles indicate the opened application and its location (1), the call stack (2), and the tab where you enter the variables you want to watch (3).

The next figure shows the Chrome debugger. Here, the bubbles indicate the script you are looking at (1), the watch expressions where you can add the variables you want to watch (3), the call stack that indicates if the code execution stops on a breakpoint (2), and the breakpoint (4). The call stack is only visible when the code execution is on hold.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 309

NoteJavaScript does not support a forward navigation, meaning that you can not jump to a method by double clicking. Instead, you either have to jump to the method during execution, or you open the file containing the method.

If you are not sure in which file exactly a piece of code is located, Firefox offers you an option to search through several files included in your page. Chrome, however, does not support this option.

Setting Breakpoints

The browser debugger supports several options for setting breakpoints. You can, for example, click once on the line number where you would like to break. To remove the breakpoint, click the respective line again. To temporarily disable or edit the breakpoint, right click on an existing breakpoint. To set a conditional breakpoint, right click on a line without breakpoint. You can also set breakpoints on a certain event or event listeners, see the option in the lower right screen area of the figure above. For more information, see the tutorials for your respective browser that are available in the internet.

NoteIn most cases after setting a breakpoint, you have to reload the page to execute the code again and to make it stop at the respective line. If you use Internet Explorer, choose Start Debugging in the developer tools to activate your breakpoint.

Adding Variables to Watch

To add a variable to the list of watched variables, open the context menu for the variable in the code line and choose Add to watch. Another option is to choose the + button at the top of the watch list to add a new line, in which you can then enter the name of the variable you want to watch.

310 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Modifying Variables

If you want to modify a variable to find out if the code works correctly with a different value, open the console, for example by choosing ESC in the debugging tool and enter the new value manually directly in the JavaScript code. To confirm the change, choose ENTER in Chrome and Execute in Firefox.

Stepping Through Executed Code

In ABAP, a yellow arrow indicates the line of code that is currently being executed. In Chrome, the arrow is red and the code line is highlighted. The following table gives an overview of the function keys for the ABAP workbench and Java Script:

Function ABAP JavaScript

Step-by-step execution, also stepping into functions and loops

F5 F11

Step-by-step execution, stepping over functions

F6 F10

Skipping the rest of the current function and stepping out to the last cursor position

F7 SHIFT+F11

Resume execution F8 F8

(Internet Explorer: F5)

1.1.4.5.5 SAPUI5 Diagnostics

SAPUI5 provides a support tool that you can run within an existing SAPUI5 application. To call the support tool, use the following shortcut: CTRL+SHIFT+ALT+S. The following sections describe the functions SAPUI5 provides in the support tool.

Activating the Debug Sources

To use the debugging function, it is important to use the debg sources. For this, set the Debug Sources function to ON.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 311

Control Tree

The control tree shows all controls that are contained in the application in a tree view. You can select controls either directly in the application by choosing CRTL+SHIFT+ALT and clicking on the control, or by selecting the control in the control tree.

The followig functions are available in the dialog:

● On the Properties tab you can change the defined properties of the selected control. In the example below, you can change the value, the text direction, and enable or disenable the control.

● The Binding Infos tab shows all existing bindings for the selected control together with additional information. To update the binding, choose Refresh.

312 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

You can also see the binding context for the selected control. To navigate to the respective controls, use the hyperlinks.

● On the Properties tab, you can add or remove breakpoints. Use the respective checkbox to add or remove a breakpoint for the get/set method of a control property.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 313

● On the Breakpoints tab, you can add or remove breakpoints for methods. You can either select the method from the dropdown box, or use auto completion. To set the breakpoint, select the method and choose Add breakpoint. To remove a breakpoint, select the red x.

Debugging a Method

To debug a method, open and activate you browser's debugging tool. If you execute a method with an active breakpoint, the script stops at the debugger statement. To open the method, use the step-over/into function of your debugger.

Debugging View

The Debugging view allows you to set breakpoints for methods on class level. Select the class from the dropdown box or enter the name of the class. Choos Add to set the breakpoint. For each class, the system shows the number of active breakpoints and all methods.

314 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.4.6 Security Concepts

The following sections provide security-related information for specific topics, such as Cross-site srcipting.

For general information on Security concepts for SAPUI5, see the Security Guide for SAPUI5.

1.1.4.6.1 Cross-Site Scripting

Cross-site scripting (XSS) is a widely known vulnerability most web sites have. This page does not provide general information about cross-site scripting but focuses on what you as an application developer using SAPUI5 can do to avoid these security issues.

To give a short info on XSS: It is about injecting script code into a web page, which is then executed in the context of the page and therefore not only can access any information which currently displayed on the screen but can either access session information contained in cookies, or send new requests to the server within the current session, or even try to exploit browser vulnerabilities to get full access to the machine the browser is running on.

Cross-site Scripting in SAPUI5-based Web Applications

AJAX frameworks in general are an interesting target for XSS exploits, as not only the HTML which is initially sent to the browser may contain vulnerabilities, but also the code which is used to visualize content on the client side

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 315

may have bugs which can be exploited to get the JavaScript coding executed on the client side. In addition to that, once a script has injected an AJAX application, it will be alive for a long time, as usually navigation will not reload the whole page which would also clean up any running JavaScript code, but stays within the same HTML document and uses a delta update mechanism to show new content.

It is important to understand that SAPUI5 is not involved in creating the HTML page which is sent to the client, so there is no way SAPUI5 can prevent XSS vulnerabilities which are contained in the HTML page itself. The application which is using the SAPUI5 rendering has to take care, according to the documentation of their server-side rendering framework, to properly escape user data, in a way that no JavaScript can be injected.

The SAPUI5 framework will take care of proper escaping for all content which is created and displayed on the screen using the controls provided by SAPUI5. There is no need for the application to HTML-escape user data, but the control API expects all data to be unescaped, so that it can be escaped as needed for the context it will be visualized.

1.1.4.6.2 URL White List Filtering

The SAPUI5 framework provides a client-side API to manage a whitelist for URLs. This whitelist can be used to validate arbitrary URLs if they are permitted or not. Internally controls which accept arbitrary HTML content like the sap.ui.richttexteditor.RichTextEditor or the sap.ui.core.HTML use the URL white list to check (sanitize) the URLs of their content and value to not infringe against the allowed URLs. The option to sanitize the value can be enabled or disabled in the respective control properly via property: RichTextEditor.sanitizeValue or HTML.sanitizeContent. For the HTML control it is disabled by default whereas for the RichTextEditor the sanitize option is enabled.

Maintaining the URL White List

The white list can be maintained with the following API:

● jQuery.sap.addUrlWhitelist● jQuery.sap.clearUrlWhitelist● jQuery.sap.getUrlWhitelist● jQuery.sap.removeUrlWhitelist

Here is an example how valid URLs can be added to the whitelist:

#!js

// jQuery.sap.addUrlWhitelist(/* protocol */ undefined, /* host */ undefined, /* port */ undefined, /* path */ undefined);

jQuery.sap.addUrlWhitelist(undefined, "www.sap.com");

jQuery.sap.addUrlWhitelist("https", "sdn.sap.com");

jQuery.sap.addUrlWhitelist(undefined, "sap.de", "1080");

316 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Validating a URL

A URL can be validated by using the following API: jQuerysapvalidateUrl.

Here is an example how a given URL is validated against the before maintained whitelist:

#!js

jQuery.sap.validateUrl("http://www.sap.com"); // => true

jQuery.sap.validateUrl("http://sdn.sap.com"); // => false (wrong protocol)

jQuery.sap.validateUrl("https://sdn.sap.com"); // => true

jQuery.sap.validateUrl("ftp://sap.de:1080/anyftpfolder"); // => true

If no whitelist is maintained the URL validity check also basically checks the URL for being defined in a valid format.

1.1.4.6.3 HTML5 Sanitizer

The HTML5 Sanitizer can be used to cleanup HTML5 code snippets by removing potentially executable javascript. For this approach the HTML4 Sanitizer by Google is reused and adapted for the usage of HTML5 coding. The Google Santizer also supports CSS3 coding. In addition the final Sanitizer makes use of the URL WhiteList which checks embedded URLs for correct formatting or against a given whitelist. For adapting the Sanitizer to support HTML5 the HTML attributes and elements were reorganized according to the actual HTML5 specification from the W3C. All types and flags were reviewed again as accurately as possible with HTML4 only elements removed, you can still see them as comments. All rules which are new or changed from the old HTML4 file are also marked "new" within the comment. The comments also state which attributes and elements are assigned to respective types and flags. All rules which were not 100% clear were analyzed in a way of similarity, so for example "audio" and "video" content behaves like images etc. URIEFFECTS state if a URL is loaded inplace within a tag where the actual document is in control of what type of content is loaded like "image" or if a new document is loaded like with "a href". LOADERTYPES state if content is loaded as sandboxed which means it is loaded within a specific surrounding player like with video content for example or if it is loaded freely without restrictions. Internally controls which accept arbitrary HTML content like the sap.ui.richttexteditor.RichTextEditor or the sap.ui.core.HTML use the HTML5 Sanitizer to sanitize the HTML code of their content and value to not infiltrate any dangerous coding. The option to sanitize the value can be enabled or disabled in the respective control properly via property: RichTextEditor.sanitizeValue or HTML.sanitizeContent. For the HTML control, it is disabled by default whereas for the RichTextEditor the sanitize option is enabled.

1.1.4.7 Security Information for SAPUI5

The following sections provide information about security-related issues of SAPUI5.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 317

1.1.4.7.1 Introduction

This Security Guide for UI development toolkit for HTML5 (SAPUI5) covers security aspects of the use of SAPUI5. It is targeted to SAPUI5 application and control developers as well as to system administrators running applications based on SAPUI5.

It is important to understand that SAPUI5 is a client-side JavaScript library, so while the library itself is designed and tested to be secure, it can not ensure the application to be secure. Unlike Web Dynpro, where the application is built against an abstract programming model and the framework handles the HTML rendering, JavaScript code and communication with the browser, in SAPUI5 the application controls the HTML output, it provides own JavaScript code which is executed on the client and it handles client/server communication.

While this brings a lot of freedom and possibilities for the application, it comes with a lot of responsibility with regards to security. Application developers need to understand the security threats and actively prohibit exploitation. Also, the correct configuration of the HTTP server, which is used, is important.

This also means common security mechanisms, which are taken for granted, like user authentication, session handling, authorization handling, or encryption are not part of SAPUI5 and need to be handled by the server-side framework and/or custom code of the application.

About this Document

The Security Guide comprises the following main sections:

● Before You Start: This secion provides links to other Security Guides that are relevant for SAPUI5.● Architectural Overview: This section gives an overview how SAPUI5 is embedded and interfacing with the

application.● Browser Security: This section provides information about the client-side security aspects of SAPUI5.● Transport Security: This section provides information about the security of data transport between client and

server.● Server Security: This section provides information about the server-side security aspects of SAPUI5.● Third Party Libraries: This section describes security aspects with regard to the third-party libraries jQuery

and datajs, which are part of SAPUI5.● Secure Programming Guide: This section describes what needs to be done in the application to ensure

security.● Using the SAPUI5 Repository based on BSP Repository

Why is Security Necessary?

With the increasing use of distributed systems and the Internet for managing business data, the demands on security are also on the rise. When using a distributed system, you need to be sure that your data and processes support your business needs without allowing unauthorized access to critical information. Protection of the user's personal data must be guaranteed and legal regulations regarding user data security must be complied with. User errors, negligence, or attempted manipulation on your system should not result in loss of information or processing time. These demands on security apply likewise to UI development toolkit for HTML5 (SAPUI5). To assist you in securing SAPUI5, we provide this Security Guide.

318 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.1.4.7.2 Before you Start

The UI development toolkit for HTML5 (SAPUI5) is not bound to any server implementation or server-side programming language and can, thus, be used with SAP NetWeaver ABAP, Java, HANA XS Engine, or any standard web server. Therefore, the corresponding Security Guides also apply to SAPUI5.

NoteWe highly recomment that you implement SAP note 1582870 for ABAP XSS escaping support.

Additional Information

For more information about specific topics, see the Quick Links as shown in the table below.

Content Quick Link on the SAP Service Marketplace or SDN

Security http://sdn.sap.com/irj/sdn/security

Security Guides http://service.sap.com/securityguide

Related SAP Notes http://service.sap.com/notes

http://service.sap.com/securitynotes

Released platforms http://service.sap.com/pam

Network security http://service.sap.com/securityguide

SAP Solution Manager http://service.sap.com/solutionmanager

SAP NetWeaver http://sdn.sap.com/irj/sdn/netweaver

Architectural Overview

UI development toolkit for HTML5 (SAPUI5) is a JavaScript library based on jQuery. It is embedded in the application using a script-tag and triggers additional requests for on demand loading of JavaScript classes, stylesheets, and other resources. For Java and ABAP a special resource handler is offered, which provides extended capabilities, and is used for all SAPUI5 internal requests.

The application usually has a server-side part and a client-side part. The server-side part can be based on any web framework, the client-side part is a web application, which is utilizing SAPUI5 for its user interface.

1.1.4.7.3 Browser Security

First of all, the browser is an untrusted client by design. The server can not rely on any information sent from the browser, as a malicious user can use a JavaScript debugger to tamper with the client code or a proxy server like fiddler to modify request data. All input validation on the client is just for convenience, the server always has to validate all the data coming from the client again.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 319

The browser also offers some possible attack vectors, especially Cross-Site-Scripting (XSS), which has to be taken care of by the application.

Cross-Site Scripting

Cross-Site-Scripting is the most prominent security issue of web applications within the last years and also the most dangerous one, as it allows so many ways of exploitation. Once malicious code is running within your browser, it can be used to steal your session cookies, to trigger requests within the current session, or even to exploit a known browser vulnerability to do native code execution.

For SAPUI5 applications, XSS vulnerabilities can exist on different levels:

● Within the HTML page or custom data transports sent to the browser from the server● Within the JavaScript Code of the application, which is processing server responses● Within the HTML renderers of SAPUI5 controls

SAPUI5 can only prevent cross-site scripting in the processing and rendering of controls. For that purpose, there is input validation on all typed element properties and output encoding done in the renderer class of controls. Be aware that there are exceptions to this, for controls which are especially built to include arbitrary HTML (like sap.ui.core.HTML).

The application is responsible for proper output encoding of all content embedded into the HTML page itself, as well as for encoding of JSON or XML data sent to the client and secure processing of this data. The application also has to take care of security of custom controls provided by the application.

HTML5

HTML5 offers a lot of new functionality, which also brings a lot of potential new security issues. This just an overview of some of the new features and possible security issues when they are used.

Local Storage

All browsers are now offering a local storage API. This API can be used to store a limited amount of data on the browser. Access to this data is limited to JavaScript code running from the same domain as it has been stored. SAPUI5 offers helper functions to access the local storage on different browsers.

The local storage of browsers is not a secure storage, so while it can be used for static data, like enumerations, applications must not store any user or application data within the local storage.

SAPUI5 is using the local storage of the browser for the history-capability of dropdown boxes and combo boxes.

320 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

WEBGL

While more and more browsers are supporting WEBGL by default, WEBGL allows accessing the graphics API of the computer on a very low level, which may also lead to low level exploits. This is the main reason Internet Explorer has no support for WebGL at all, Microsoft recently stated, that they are not going to support WebGL as they think it can not be implemented in a secure way.

SAPUI5 is currently not using WEBGL.

WebSockets

While WebSockets offer great new possibilities for the client/server communication of web applications, there have been many security issues rising while the first implementations were done by the browser vendors. Standardization of WebSockets has reached a stable state with RFC 6455 and is now implemented beginning with Chrome 16, Firefox 11 and Internet Explorer 10. Even if the browser implementations themselfes prove to be secure, using WebSockets may require additional security measures on the client.

SAPUI5 is currently not using WebSockets.

Postmessage/Onmessage

This is another great feature in the HTML5 area, which can lead to massive security issues when not used correctly. postMessage allows inter-window-communication between windows from different domains. So basically this opens a hole in the same origin policy currently implemented in the browser. As soon you are subscribing to the onMessage event, you can receive messages from any other browser window, the application is responsible to check the originating domain and only to process messages which have been sent by trusted domains.

SAPUI5 is utilizing postMessage for its debugging and tracing functionality.

1.1.4.7.4 Transport Security

Of course the best security on the client and server does not help, if the data transport between client and server can be read, intercepted, or even modified by an attacker. Per default HTTP communication is stateless and unencrypted, which makes it necessary to configure it in a way that it is using encrypted connections and to add session handling on top using either cookies or URL rewriting.

Encryption

Sending the HTTP protocol over a SSL secured connection is not only standardized, but also required for SAP applications.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 321

SAPUI5 fully supports the use of HTTPS, but there are some restrictions regarding the CDN version of SAPUI5 when HTTPS is used. It is recommended to enable or at least to test SSL connections in an early stage of application development, as usually switching to HTTPS causes some issues. First of all, when the application is started using HTTPS, the SAPUI5 library also has to be loaded from an HTTPS server. Second, Internet Explorer 8 and 9 have some additional restrictions regarding cross origin requests with HTTPS, which are related to the security zone concept.

Session Security

Even if the data transport is secured using SSL, there are possibilities to hijack such a secure connection and sending malicious requests from the client. Cross-site request forgery and session fixation are two of the prominent examples of this class of attacks.

SAPUI5 does only provide XSRF prevention for the data, which is sent to the server by SAPUI5. Currently this only happens in the OData Model, where a XSRF token is read from the server and used for subsequent write requests.

Application is responsible for using XSRF header or other mechanisms to prevent XSRF for all other server communication triggered by the application.

1.1.4.7.5 Server Security

UI development toolkit for HTML5 (SAPUI5) only ships a small server-side part to support loading of resources by the client framework. The use of the resource handlers is not mandatory, SAPUI5 also offers a static version of the libraries, which can be used with an arbitrary HTTP server.

Cross Origin Resource Sharing

Usually the XMLHttpRequest for security reasons does only allow accessing resources from the same domain as the originating document. As their are a lot of web-based services available today, starting with RSS or Atom feeds, WebServices or OData services, there is a need to be able to also access data sources from different domains within the browser, which was adressed with the CORS (Cross Origin Resource Sharing) standard. This allows the server to set special headers on their responses, which are telling the XMLHttpRequest object, whether it is allowed to process the requested data or not.

This CORS capability also plays an important role in SAPUI5 based applications. In case the application itself and the data visualized are coming from different servers, the CORS header has to be configured correctly on the data providing server, to allow the application server domain to access the data.

SAPUI5 is using CORS header on its CDN based library to be able to load additional scripts, styles, and resources from the CDN server.

322 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Resource Handler (Java)

The resource handler for Java provides some configuration options (context parameters in the web.xml). It is possible to enable CORS, configuring the cache control and activating a development mode. For more information about the configuration options see the topic Resource Handling in the user interface add-on developer guide on the Help Portal (http://help.sap.com/nw_uiaddon).

For productive use of the resource handler, deactivate the development mode and remove the configuration option com.sap.ui5.resource.DEV_MODE in the web.xml.

Resource Handler (ABAP)

The resource handler for ABAP is not configurable. It is used to serve the resources from the mime repository.

Resource Handler for Application Resources (ABAP, NW 7.x)

The resource handler for application resources for ABAP, NW 7.x is not configurable. It is used to serve the resources from the SAPUI5 repository based on BSP repository.

Proxy Servlet (Java)

SAPUI5 provides a SimpleProxyServlet. This proxy servlet can be used on a local server only for local requests to access data from other domains. This is useful to avoid cross domain issues when fetching data from another domain for testing purposes. Also for the SAPUI5 tools this is required since the local testing needs to access data from the remote ABAP server. Due to security reasons this proxy servlet is limited to localhost usage only and cannot be used by requests from other domains.

1.1.4.7.6 Third-Party Libraries

The UI development toolkit for HTML5 (SAPUI5) ships with third-party libraries. jQuery is mandatory as SAPUI5 is based on it, and datajs is needed in case OData services should be used.

jQuery

jQuery does not have any security-related documentation on their site, but they are known to be aware of security and usually reacting quickly in case security issues are found within their library.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 323

SAPUI5 includes different versions of jQuery together with their own libraries, so also has the possibility to add custom security fixes to jQuery, if necessary.

datajs

datajs does not have any security-related documentation on their site.

SAPUI5 includes the datajs library and can add custom security fixes, if necessary.

Libraries Included by the Application

Applications based on SAPUI5 are allowed from a technical point of view to include arbitrary custom libraries within their application. SAPUI5 can, of course, not give any statement about the security of third-party libraries and can not ensure security of third-party libraries. The application has full responsibility for doing an security assessment of third-party libraries before using them and for embedding and using them in a secure manner.

1.1.4.7.7 Secure Programming Guide

Input Validation

From the application point of view, the validaton of user input must be done on the server and can be done optionally on the client, and can be achieved by using two-way data binding and model types.

From the control point of view, the input of control properties must be validated, so integer properties only accept integers and enumeration properties only accept an existing enumeration value. While this sounds obivous, in JavaScript it is not. The type system of JavaScript does not do type validation on assignment.

Output Encoding

All data sent from the server must be properly output encoded according to the context they are contained in. For more information, see the XSS Secure Programming Guide.

Content, which is created on the client side either for display within the browser or for data transport, needs to be properly output encoded with the encoding methods provided by UI development toolkit for HTML5 (SAPUI5). There are methods for encoding HTML, XML, JavaScript, CSS and URI components.

All controls in SAPUI5 libraries properly encode their data, except for HTML-control and XMLView. The latter two are explicitely built to display arbitrary HTML content. If applications use these two controls and provide unsecure HTML content, they have to check/validate the content on their own.

324 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteUsing an XMLView with application controlled secure HTML content together with standard SAPUI5 controls (other than HTML and XMLView) containing potentially unsecure data is also safe. Only untrusted HTML content is critical.

SAPUI5 does not yet provide an HTML sanitizer.

URL Validation

URL validation should take place on the server-side when possible. In case URLs are entered on the client-side or are loaded from an external service, SAPUI5 offers an URL validator, which can be used to whether a URL is well formed and properly encoded. It also contains a configurable white liste to restrict URLs to certain protocols or certain hosts. Initially, the white list only checks for the http, https, and ftp protocols, but nothing else. Applications should define their own whitelist.

Cash Settings

The application has to take care that caching of data is disabled by setting appropriate HTTP headers on the server-side.

Static resources from SAPUI5 or from the application are not security relevant and are excluded from this rule, so they can safely be cached on the client.

User Management / Authentication

SAPUI5 does not provide any authorization or user management. An application, which implements such facilities based on SAPUI5 has to make sure that SSL is enabled to prevent cleartext passwords sent over the wire. Applications must not store any logon information on the client.

Local Storage

The local storage of browsers is not a secure storage, so while it can be used for static data, like enumerations, applications must not store any user or application data within the local storage.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 325

1.1.4.7.8 Using the SAPUI5 Repository Based on BSP Repository

Using the SAPUI5 Repository Team Provider

The SAPUI5 repository team provider connected against a SAP NW 7.31 ABAP system with UI add-on can be used to synchronize the SAPUI5 application resources between Eclipse and the SAPUI5 repository on the ABAP system.

For more information on the use of SAPUI5 repository team provider, see the Security Guide for ABAP development tools, which is part of the ABAP Development User Guide and the SAP NetWeaver Security Guide.

Authorization Objects for SAPUI5 Repository Team Provider

Authorization object Description

S_DEVELOP The authorization object S_DEVELOP is needed to create, update and delete SAPUI5 applications in the SAPUI5 Repository.

S_ICF_ADM The authorization object S_ICF_ADM is needed to create the SAPUI5 application specific ICF node under /sap/bc/ui5_ui5/

S_TCODE The authorization object S_TCODE is needed to create the SAPUI5 application specific ICF node under /sap/bc/ui5_ui5/

S_TRANSPORT The authorization object S_TRANSPRT is used to create new transport request or new task.

S_CTS_ADMI The authorization object S_CTS_ADMI is needed to transport SAPUI5 applications.

S_CTS_SADM The authorization object S_CTS_SADM is needed to transport SAPUI5 applications.

S_ADT_RES The authorization object S_ADT_RES is used for the communication between Eclipse and the ABAP Backend via the SAPUI5 Repository Team Provider.

S_RFC The authorization object S_RFC is used for the communication between Eclipse and the ABAP Backend via the SAPUI5 Repository Team Provider.

For more information about authority checks and working with authorization objects, see SAP NetWeaver 7.0x Security Guides (Complete) on the SAP Help Portal at http://help.sap.com/netweaver.

Delivered Virus Scan Profiles

When uploading files to the SAPUI5 repository, you can perform a virus scan.

As of SAP NetWeaver 7.00 with UI add-on, SAP delivers the following virus scan profile for ABAP within the UI add-on: /UI/UI5_INFRA_APP/REP_DT_PUT. This profile is used by the SAPUI5 repository API to store files in the SAPUI5 repository based on BSP repository. For example: The upload of a local file using SAPUI5 repository API /UI5/CL_UI5_REP_DT, method /UI5/IF_UI5_REP_DT~PUT_FILE from 7.00 on, or the SAPUI5 repository team provider in 7.31.

326 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The profile is deactivated when delivered. To activate it, first create at least one basis profile and save it as the default profile. You can then activate one of the delivered profiles. By default, it links to a reference profile, which is the default profile. For more information, see ABAB-specific Configuration of the Virus Scan Interface (7.00) and ABAP-specific Configuration of the Virus Scan Profile (7.31)

Executing SAPUI5 Applications from the SAPUI5 Repository

The SAPUI5 application can be executed from the NW 7.X ABAP System by retrieving the SAPUI5 application resources from the SAPUI5 repository based on BSP repository with the help of an ICF handler.

Delivered ICF Nodes

For the execution of SAPUI5 applications from the SAPUI5 repository, SAP delivers ICF node /sap/bc/ui5_ui5/. Below that ICF node and ICF node exists for each SAPUI5 application.

NoteAll services delivered by SAP (such as the /sap/bc/ui5_ui5/ service for executing SAPUI5 applications) are initially inactive. Also each new service that you create has status inactive. Before you work with the ICF, you must activate the services you require.

For more information, see also Activating and Deactivating ICF Services (7.00 EhP3) and Activating and Deactivating ICF Services in the SAP Library for SAP NetWeaver on SAP Help Portal at SAP NetWeaver SAP NetWeaver Library SAP NetWeaver by Key Capability Application Platform by Key Capability Connectivity Components of SAP Communication Technology Communication between ABAP and Non-ABAP Technologies

Internet Communication Framework Development .

For more information about ICF security, see SAP NetWeaver Security Guide on SAP Service Marketplace under SAP NetWeaver 7.0x Security Guides (Complete) SAP NetWeaver 7.0x Security Guides (Online Version)

Security Guides for Connectivity and Interoperability Technologies RFC/ICF Security Guide .

Authorization Objects

No specific authorization objects are needed to execute SAPUI5 applications from the SAPUI5 repository.

As for ICF service nodes in general, authorization for specific ICF service nodes can be restricted, see Defining Service Data in the SAP Library for SAP NetWeaver on SAP Help Portal under SAP NetWeaver SAP NetWeaver Library SAP NetWeaver by Key Capability Connectivity Components of SAP Communication Technology Communication between ABAP and Non-ABAP Technologies Internet Communication Framework

Development Server-Side Development Creating and Configuring ICF Services Create Service and Authorization Object S_ICF (7.00 EHP3) or SAP Library for SAP NetWeaver on SAP Help Portal under SAP NetWeaver SAP NetWeaver Library SAP NetWeaver by Key Capability Application Platform by Key Capability Connectivity Components of SAP Communication Technology Communication between ABAP and Non-ABAP Technologies Internet Communication Framework Development .

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 327

Tracking Coding Changes and Text Changes in the SAPUI5 Repository

Code changes can be tracked by using the usual ABAP version control of the corresponding resource file. A new version is created when a new transport is written.

Text changes can be tracked by using the "Table History" transaction (SCU3), the relevant tables for SAPUI5 texts are /UI5/TREP_TEXT and /UI5/TREP_TEXT_T for the translated text. Table logging has to be activated in the system for this functionality.

1.2 SAP NetWeaver User Interface Services Developer Guide

SAP NetWeaver user interface services offers a set of back-end services and front-end services. To decouple your UI, you use OData services for ABAP-based back-end systems based on an OData channel that is part of SAP NetWeaver Gateway. To couple to a new UI technology, you use front-end services.

APIs are available on three different layers:

● JavaScript services provide integration capabilities and simplify access to data from back-end systems.● OData services are consumed by the front-end services and allow you to retrieve data from back-end systems

using SAP NetWeaver Gateway.● ABAP APIs are consumed by the OData services mentioned above. You can use these APIs to create your own

services for maximum flexibility.

Related Information

Navigation Using Callable Entities [page 328]

JavaScript Services [page 332]OData Services [page 363]ABAP APIs [page 386]

1.2.1 Navigation Using Callable Entities

Concept

Callable entities allow applications built with any technology that consume OData services to navigate to applications related to that data, for example, what other applications can a user start in relation to a particular product. Callable entities work independently of the used UI technology (for example, SAPUI5 or Web Dynpro ABAP) of the target application or a shell (SAP NetWeaver Business Client, Portal, or other).

328 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

It is not necessary to use special SAP APIs or to expose the UI framework and the applications-specific syntax of the target applications.

NoteOData enables applications on any platform to easily consume data provided by any SAP platform.

An OData service developer needs to provide only the details about the target application on the server side that will become a URL link on the client side and can be used by the application developer (user interface developer). The technical processing of the request is hidden from the service user by ABAP and JavaScript libraries.

● An ABAP API is used to enable OData service developers to easily expose navigation targets (for example, to Web Dynpro applications) as media link entries in their services. Media link entries that call applications are named callable entities.

● Out of the box support for navigation targets defined in the report launchpad● Alternatively, there is a BAdI that enables integrating any other navigation target repository which you can

register in transaction /UI2/NAV.

The building blocks to enable callable entities are as follows:

● Media link entriesMedial link entries link to information outside the OData world. This information can be passive (for example, a PDF documentation), or active (for example, a Web Dynpro application). Media links are based on the standards defined by OData Atom and OData JSON. Callable entities constitute a subcategory of media link entries which link to active information. They are used to return an HTML page which can be processed by any browser on any platform. That page will then use the appropriate navigation mechanism based on the environment (depending on wether used with or without SAP NetWeaver Business Client).

● Specific helper classes to create callable entities● A plugin concept that ties the helper classes to the individual repositories

Modeling

● Windows application (WPF/C++)● Browser application (HTML/JavaScript)● iOS (iPad) application (Objective-C)● Other applications (other language)

The application that consumes the OData services can be based on any type of technology, for example:

● Callable entities are media link entries. They are defined as follows as regular entities. The OData properties have the meta data for these resources, for example, the title of a picture, an audio or PDF file or a navigation target.

● Callable Entities belong to an Entity:

○ Header-Item (one to many) relationship: Navigation property from the entity to the related CEs.○ A CE has exactly one parent entity: Navigation property from CE to related parent entity omitted.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 329

Architecture

1. A user starts an application.2. The application requests data from an SAP platform.3. The OData service serves the data.4. The application requests callable entity data (title of links, media type, and media URLs).5. The OData service uses its platforms navigation façade to create the callable entity data.6. The application visualizes the callable entities, for example, as hyperlinks.7. The user clicks on a link.

NoteWhen the user clicks the link to edit the data, he must know the OData service that is connected to the object.

8. The application passes the media URL of the callable entity to an HTML container.9. The container executes the URL, that is, it requests the bootstrap.10. The OData service passes the business context to its platform's navigation façade and puts the resulting

HTML into the response.11. The HTML interprets the received HTML page and executes the JavaScript of the bootstrap.12. The bootstrap initiates the optimal navigation to real target application.

1.2.1.1 Adding Repositories (Assigning Navigation Providers)

This section describes how a role developer adds a repository (navigation provider).

Customizing View for Semantic Object and Navigation Provider

Different navigation link categories have different purposes. To categorize these a semantic object has been introduced, for example, Products. For this object you define which repository (navigation provider) should be used. In the standard implementation such a navigation provider is the report launchpad. In the report launchpad, you can specify navigation link targets. Hence there is a generic way to specify semantic objects and assign the navigation targets.

The Customizing of the semantic object, the assignment of the navigation provider and of the links in the repository is made in the view cluster using transaction /ui2/nav:

● In the view cluster you have to specify the semantic object : Toplevel - Register Semantic Object● On the next level you specify which navigation providers are used for the semantic object: Second Level -

Register navigation provider● On the lowest level the specification of the repository keys is made: Register Keys for navigation provider.

Here you can specify one or more key/value-pairs to identify in an unique manner the related navigation targets in the repository of the navigation provider.You define new navigation providers in transaction /ui2/navprov.

330 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

BAdI-Implementation for Navigation Provider

If you want to use a new repository for navigation targets, you have to create a BAdI Implementation. In the user interface add-on, the launchpad repository is used as a navigation provider. For this a special BAdI implementation is made in the enhancement implementation /UI2/EI_NAVIGATION_LPD.

The enhancement spot used is /UI2/ES_NAVIGATION. Within this enhancement spot you find the BAdI definition /UI2/BADI_NAVIGATION and BAdI interface /UI2/IF_BADI_NAVIGATION.

To include a new navigation provider, you have to create a BAdI implementation of the BAdI /UI2/BADI_NAVIGATION.

For this implementation, the interface /UI2/IF_BADI_NAVIGATION has to be implemented, including 2 methods:

● GET_TARGETS: Method to retrieve target information of repository (List)● GET_TARGET_DATA: Method to get target information details for the navigation (resolved link)● GET_KEY_NAMES: Method to get key names for navigation provider (value help)● GET_KEY_VALUES: Method to get key values for navigation provider (value help)

You also have to specify a filter for your BAdI implementation. Take the value of the navigation provider for the filter.

1.2.1.2 Using Callable Entities as OData Developer

This section describes how you use callable entities as OData developer.

Using the Factory Class

Use the factory class /UI2/CL_NAVIGATION_FACTORY to access the target link lists for semantic objects and to obtain the navigation details of the callable entity for an entry of the target link list. The precondition for this generic access is the maintenance of data for semantic objects and navigation provider and the BAdI implementation of the assigned repositories (navigation provider). The class can be used especially in your OData services.

Create an instance of the factory class:

Code SyntaxDATA: lr type ref to /UI2/CL_NAVIGATION_FACTORY

create object lr.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 331

● Retrieving the target link list (ID, description) of a semantic objectUse the following code to obtain all navigation links of your semantic object 'PRODUCTS':

Code Syntaxlr->GET_TARGETS( IV_NAVIGATION_OBJECT = 'PRODUCTS' )

● Obtaining the bootstrap-HTML for an entry of the target link listUse the following code to obtain the navigation target HTML for the navigation on the UI:

Code Syntaxlr->GET_TARGET_HTML( Importing

IV_ID = 'ID of NAV TARGET XYZ'

IT_BUSINESS_PARAMS = 'Possible Business Parameter' ... )

Creating an OData Service for the Navigation Provider

An OData service is required to enable the navigation based on callable entities. You can use the SAP NetWeaver Gateway Service Builder to model and generate your OData service.

Using SAP NetWeaver Gateway to Create an OData Service

Start transaction SEGW. As an example you can refer to system U00 (client 010). The service /UI2/ESPM_NAV with the description "UI2 Demo on UI Navigation via Callable Entities". In the generation process of the Service Builder, several classes are generated in the package /UI2/SERVICES_ESPM_NAV (see transaction /nse80).

Then special methods have to be coded for the data access, here class /UI2/CL_ESPM_NAV_DPC_EXT (Data Provider Secondary Class).

1.2.2 JavaScript Services

You can find the JSDocs for SAP NetWeaver user interface services on SAP Help Portal at http://help.sap.com/javadocs/ui-services.

1.2.2.1 CHIP Development

A CHIP (Collaborative Human Interface Part)is an encapsulated, stateful piece of software used to provide functions in collaboration with other CHIPs in a Page Builder page or side panel. All available CHIPs are registered in a library (CHIP catalog). The CHIP model describes capabilities of a CHIP and is not based on a specific UI technology. Client-side rendering CHIPS (CSR CHIPs) are CHIPs that use client-side rendering capabilities, such as SAPUI5.

332 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.2.1.1 CHIP Specification Schema

The CHIP specification schema is described in an XSD file. The current schema is part of your installation and can

be found here: http://<server>:<port>/sap/public/bc/ui2/services/sap/ui2/srvc/chipdefinition.xsd

The CHIP description consist of the following elements:

● implementationThis element specifies the implementation details and is mandatory.

● appearanceThis element specifies the title and a description for the CHIP.

● contractsThis element specifies the contracts that can be implemented. For more information, see API Reference.

● parametersThis element specifies additional parameters that can be defined.

1.2.2.1.2 CHIP Definition XML

In the CHIP definition file you define the elements of the CHIP specification schema used in your CHIP. Whatever you define here can be accessed from your coding using the CHIP API.

Table 2:Element Description

implementation As implementation sapui5 is supported.

For viewName specify the name of the sapui5 view containing the content of your CHIP. The viewName comprises package path, the name of the view and the file extension, for example tests.sample.Myview.view.xml.

The following sapui5 view types are supported:

● Javascript with file extension js● XML with file extension xml● JSON with file extension json

appearance Set the title and the description of your CHIP.

contracts Define the contracts used in your CHIP. In the example below the fullscreen contract is used.

parameters These parameters can, for example be used to determine in which catalogs your CHIP is displayed.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 333

ExampleCHIP Definition XML

The following example shows a CHIP definition with an sapui5 view of type xml, with a title and two contracts: fullscreen and a configuration that specifies a catalog:

<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2012 SAP AG, All Rights Reserved --><chip xmlns="http://schemas.sap.com/sapui2/services/Chip/1"> <implementation> <sapui5> <viewName>sap.ui2.tests.fullsize.Full.view.xml</viewName> </sapui5> </implementation> <appearance> <title>Chip taking full size</title> </appearance> <contracts> <consume id="fullscreen"/> <consume id="configuration"> <parameters> <parameter name=“parameterName“>defaultValue</parameter> </parameters> </consume> </contracts></chip>

1.2.2.1.3 Creating a CSR CHIP

For developing client-side rendering CHIPs (CSR CHIPs) you basically use the UI Development Toolkit for HTML5 (SAPUI5). The SAPUI5 application is extended by a CHIP definition, which is used to enable the application to run in a page builder.

1. Create an SAPUI5 Application Project with an SAPUI5 view.2. Insert the chipdefinition.xsd into your project. The schema is part of your installation and can be found

here: http://<server>:<port>/sap/public/bc/ui2/services/sap/ui2/srvc/chipdefinition.xsd

3. Create a CHIP definition xml file, e. g. called mychip.chip.xml and define the entries. For more information, see CHIP Definition XML [page 333].

Tip

To enable XML validation and code completion, go to Windows Preferences Web and XML XML Catalog and create an entry for the chipdefinition.xsd file.

4. To access the CHIP API, proceed as described under Accessing the CHIP API and the contracts [page 335].5. Create the content of your CHIP with the SAPUI5 means.

334 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.2.1.4 Accessing the CHIP API and the contracts

With the CHIP API you can access the contracts and all elements defined in the CHIP definition file.

1. To access the CHIP API from the controller of your project, retrieve it via the SAPUI5 view:

(function () { "use strict"; sap.ui.controller("someController", { onInit: function () { var oChipApi = this.getView().getViewData().chip; ... }, ... });}());

2. You now can access the contracts as properties as described in the following topics.As a prerequisite for using a contract, you must consume this contract in the CHIP definition XML. The respective property is then available in the CHIP API object.

Related Information

CHIP Definition XML [page 333]

Accessing the "bag" Contract

You can use property bags to persist any key-value pairs in order to store settings for a CHIP instance.

Using property bags, you can persist page settings in the following scopes:

● Personalization: User-specific settings (These settings supersede Customizing and Configuration settings.)● Customizing: Client-specific settings (These settings supersede Configuration settings, but can be

superseded by Personalization settings.)● Configuration: System-wide settings (These settings can be superseded by Customizing and Personalization

settings.)

As a prerequisite, you have to consume the bag contract in the CHIP definition XML.

The bag property is then available in the CHIP API object.

NoteCHIPs are not the only objects that can store properties in bags. Property bags may also be created by a client-side page builder.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 335

ExampleCode Example

var oChipApi = this.getView().getViewData().chip, aBagIds = oChipApi.bag.getBagIds(); oBag = oChipApi.bag.getBag("sample_bag");

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.bag.htmlPersisting Settings in Property Bags [page 350]You can use property bags to persist any key-value pairs in order to store settings for your application.

Storing Page-Specific Settings [page 348]This topic describes different possibilities to store page-specific settings.

Accessing the "configuration" Contract

As a prerequisite, you have to consume the configuration contract and declare names for all configuration parameters in the CHIP definition XML. Optionally, you can also define default values for the configuration parameters.

The configuration property is then available in the CHIP API object. It provides the method chip.configuration.getParameterValueAsString(), which allows you to read parameters that have been declared in the CHIP definition XML.

ExampleCode Example

var oChipApi = this.getView().getViewData().chip, sConfigurationValue = oChipApi.configuration.getParameterValueAsString("parameterName");

ExampleExample for Configuration

<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2012 SAP AG, All Rights Reserved --><chip xmlns="http://schemas.sap.com/sapui2/services/Chip/1"> <implementation> <sapui5> <viewName>sap.ui2.chips.sample.links.Links.view.xml</viewName> </sapui5> </implementation>

336 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

<appearance> <title>Link List Sample Chip</title> </appearance> <contracts> <consume id="configuration"> <parameters> <parameter name="columns">3</parameter> <parameter name="id"></parameter> <parameter name="showChildren">true</parameter> </parameters> </consume> <consume id="fullscreen" /> <consume id="navigation" /> <consume id="refresh" /> <consume id="url" /> </contracts></chip>

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.configuration.html

Accessing the "writeConfiguration" Contract

As a prerequisite, you have to consume the writeConfiguration contract as well as the configuration contract in the CHIP definition XML.

The writeConfiguration property is then available in the CHIP API object. It provides the method chip.writeConfiguration.setParameterValues(), which allows mass updates of parameters that have been declared in the CHIP definition XML.

NoteOnly string values are supported.

The default error handler is usually provided by the page builder.

ExampleCode Example

var oChipApi = this.getView().getViewData().chip;

oChipApi.writeConfiguration.setParameterValues({ columns: "2", id: "07UI2_EPM0BUI2_EPMDEMO00", showChildren: "false"}, function () { // continue in case of success...}, function (sErrorMessage) {

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 337

alert("write configuration failed: “ + sErrorMessage); });

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.writeConfiguration.html

Accessing the "fullscreen" Contract

As a prerequisite, you have to consume the fullscreen contract in the CHIP definition XML.

The fullscreen property is then available in the CHIP API object. It provides the following methods:

● chip.fullscreen.attachFullscreen()You can use this event handler to find out when your CHIP should display a different view, for example when the user switches the fullscreen mode.

● chip.fullscreen.getFullscreen()You can use this method to find out whether fullscreen mode is on.

● chip.fullscreen.setFullscreen()You can use this method to switch fullscreen mode from within your CHIP.

ExampleCode Example

var oChipApi = this.getView().getViewData().chip, bIsFullscreen = oChipApi.fullscreen.getFullscreen();

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.fullscreen.html

Accessing the "navigation" Contract

As a prerequisite, you have to consume the navigation contract in the CHIP definition XML.

The navigation property is then available in the CHIP API object. It provides the method chip.navigation.navigateToUrl(), which allows you to navigate to a URL.

338 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

ExampleCode Example

var oChipApi = this.getView().getViewData().chip;oChipApi.navigation.navigateToUrl("http://www.sap.com");

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.navigation.html

Accessing the "refresh" Contract

As a prerequisite, you have to consume the refresh contract in the CHIP definition XML.

The refresh property is then available in the CHIP API object. It provides the method chip.refresh.attachRefresh() to learn when a refresh is requested.

ExampleCode Example

var oChipApi = this.getView().getViewData().chip;oChipApi.refresh.attachRefresh(function (){ // do refresh now});

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.refresh.html

Accessing the "searchProvider" Contract

As a prerequisite, you have to consume the searchProvider contract in the CHIP definition XML.

The searchProvider property is then available in the CHIP API object. It provides the method chip.searchProvider.addSearchProvider() for adding a search provider.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 339

ExampleCode Example

var oChipApi = this.getView().getViewData().chip;oChipApi.searchProvider.addSearchProvider("http://foo.sap.corp/searchProvider.xml");

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.searchProvider.html

Accessing the "url" Contract

As a prerequisite, you have to consume the url contract in the CHIP definition XML.

The url property is then available in the CHIP API object. It provides the method chip.url.toAbsoluteUrl() to convert a relative URL into an absolute URL.

ExampleCode Example

var oChipApi = this.getView().getViewData().chip, sImageUrl = oChipApi.url.toAbsoluteUrl("sap/ui2/chips/sample/links/loading.gif");

Related Information

CHIP Definition XML [page 333]http://help.sap.com/javadocs/ui-services/services/symbols/chip.url.html

1.2.2.2 Creating a Client-Side Page Builder

This section explains the basics of creating a Web application which acts as a client-side page builder. This Web application is based on SAPUI5. It loads a page and CHIP descriptions using the back-end services for client-side page building (page building services, PBS) and displays the page and its embedded CHIP instances in a Web browser.

340 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

This section describes how you can create your own client-side page builder. It describes the required steps and includes example code for a minimalist client-side page builder.

NoteThe Suite Page Builder that is shipped with user interface add-on for SAP NetWeaver is another example for a client-side page builder. It consumes the same JavaScript services as the examples in this section.

JavaScript services provided by SAP NetWeaver user interface services offer the following functionality:

● Create, read, update and delete operations on catalog, page, CHIP, CHIP instance and property bag data, based on back-end services for client-side page building and their entity data model (EDM).The back-end services for client-side page building are based on OData. A JavaScript facade simplifies access to the OData services.For more information, see Class sap.ui2.srvc.PageBuildingService.

● A JavaScript object model for catalogs, pages, CHIPS, CHIP instances and property bags, which encapsulates and enriches the data retrieved from the page building services, and mimics the EDM used there.There is a factory to create these objects. For more information, see Class sap.ui2.srvc.Factory.

● Helper functionsFor more information, see Namespace sap.ui2.srvc.

1.2.2.2.1 Creating a Minimalist Page Builder

Displaying a page in a client-side page builder includes the following basic steps:

1. Load the required scripts for SAPUI5 and SAP NetWeaver user interface services.2. Determine the name of the page to be displayed.3. Initialize the sap.ui2.srvc.PageBuildingService facade for the page building services (PBS).

4. Create a page object wrapper using sap.ui2.srvc.Factory (based on the the PBS facade) and tell the wrapper to load its data.

5. Loop over the page's CHIP instances:a) Get a SAPUI5 control for each CHIP's UI.b) Arrange these SAPUI5 controls on a Web page.

You can find a complete example below. The single steps are described in detail in the following topics.

<!DOCTYPE html><!-- Copyright (c) 2012 SAP AG, All Rights Reserved --><html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <title>A Minimalist Page Builder</title>

<script src="/sap/public/bc/ui2/shell-api/sap/ui2/shell/shell.js"></script>

<script id="sap-ui-bootstrap" src="/sap/public/bc/ui5_ui5/resources/sap-ui-core.js" data-sap-ui-evt-oninit="main();" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection"> </script>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 341

<script type="text/javascript"> "use strict"; /*global alert, jQuery, sap, window */

function defaultError(sText) { alert(sText); }

function onTitleChange(oTitle, oChipInstance) { oTitle.setText(oChipInstance.getTitle()); }

function onSuccess(oLayout, oPage) { var aChipInstances = oPage.getChipInstances(), i, n, oChipInstance, oTitle, for (i = 0, n = aChipInstances.length; i < n; i += 1) { oChipInstance = aChipInstances[i]; oTitle = new sap.ui.commons.TextView({ text: oChipInstance.getTitle() }); oChipInstance.attachTitleChange(onTitleChange.bind(null, oTitle)); oLayout.addContent(oTitle) .addContent(oChipInstance.getImplementationAsSapui5()); } }

function main() { var sPageId, oFactory, oLayout, oPage;

// Register the module path for sap.ui2.srvc jQuery.sap.registerModulePath("sap.ui2.srvc", "/sap/public/bc/ui2/services/sap/ui2/srvc");

// Register the contracts jQuery.sap.require("sap.ui2.srvc.contracts.bag"); jQuery.sap.require("sap.ui2.srvc.contracts.configuration"); jQuery.sap.require("sap.ui2.srvc.contracts.fullscreen"); jQuery.sap.require("sap.ui2.srvc.contracts.navigation"); jQuery.sap.require("sap.ui2.srvc.contracts.refresh"); jQuery.sap.require("sap.ui2.srvc.contracts.searchProvider"); jQuery.sap.require("sap.ui2.srvc.contracts.url");

// Require sap.ui2.srvc.factory (for the Factory) jQuery.sap.require("sap.ui2.srvc.factory");

sPageId = jQuery.sap.getUriParameters().get("page") || "_CHANGE_THIS_DEFAULT_"; oFactory = sap.ui2.srvc .createFactory("/sap/opu/odata/UI2/PAGE_BUILDER_PERS/", defaultError); oLayout = new sap.ui.commons.layout.VerticalLayout(); oPage = oFactory.createPage(sPageId, onSuccess.bind(null, oLayout), defaultError);

oLayout.placeAt("canvas"); }

// Set the default error handler. // Note: this will be ignored in IE9 while debugging is enabled. window.onerror = defaultError; </script> </head> <body class="sapUiBody" role="application"> <div id="canvas"></div>

342 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

</body></html>

The body section is very minimalist. Note that the body has an attribute role="application". This attribute is a hint to the screen reader to treat this HTML page as an application rather than a Web page.

Including SAP NetWeaver User Interface Services Scripts

The page builder needs to load a bundle of JavaScript files provided by SAP NetWeaver user interface services.

One of the tasks of the shell.js script is to retrieve the user settings from the ABAP system and apply them to SAPUI5. The script can only perform this task if it is included in the HTML file before the SAPUI5 bootstrap.

<script src="/sap/public/bc/ui2/shell-api/sap/ui2/shell/shell.js"></script>

All other scripts can be required using jQuery.sap.require. You only need to require the scripts that your code uses directly. It is usually sufficient to require factory.js.

Additionally, your page builder has to require all scripts related to contracts (sap.ui2.srvc.contracts.*). This is done in the main() function.

CautionIncluding shell.js automatically performs domain relaxation in the same way as Web Dynpro, and you cannot influence its behavior.

NoteIncluding shell.js automatically transports user settings such as theme, language, and RTL settings to SAPUI5. For this to take effect correctly, you must include shell.js before the SAPUI5 bootstrap. This has the following consequences:

● You must not refer to SAPUI5 libraries other than sap.ui.core until the SAPUI5 core is initialized. Use sap.ui.getCore().attachInit() or an equivalent (for example <script id="sap-ui-bootstrap" data-sap-ui-evt-oninit="..." ...></script>).

● You cannot include style sheets directly from the HTML page in order to override SAPUI5 style classes. You can use jQuery.sap.includeStyleSheet() instead.

Related Information

Using SAP NetWeaver User Interface Services in SAPUI5 Applications [page 357]This code example shows how to run a SAPUI5 application in a shell with the settings of the user who is currently logged on, like language, date, time and number formats, and theme.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 343

SAPUI5 Bootstrap

SAPUI5 is loaded using the standard procedure. The following code requests SAPUI5 to run your main function as soon as SAPUI5 has finished its initialization:

<script id="sap-ui-bootstrap" src="/sap/public/bc/ui5_ui5/resources/sap-ui-core.js" data-sap-ui-evt-oninit="main();" data-sap-ui-libs="sap.ui.commons" data-sap-ui-theme="sap_goldreflection"> </script>

Main Function

Main Function

The function main function provides a local scope for our variables. It is called as soon as SAPUI5 has finished its initialization (see the data-sap-ui-evt-oninit attribute in the sap-ui-bootstrap script tag in the header of the page). The main function executes the first steps.

Requiring the Necessary Scripts

The contracts and some other scripts have to be required so that they can be used in the page builder. Before you can require modules from SAP NetWeaver User Interface Services, you have to specify their location.

// Register the module path for sap.ui2.srvc jQuery.sap.registerModulePath("sap.ui2.srvc", "/sap/public/bc/ui2/services/sap/ui2/srvc");

// Register the contracts jQuery.sap.require("sap.ui2.srvc.contracts.bag"); jQuery.sap.require("sap.ui2.srvc.contracts.configuration"); jQuery.sap.require("sap.ui2.srvc.contracts.fullscreen"); jQuery.sap.require("sap.ui2.srvc.contracts.navigation"); jQuery.sap.require("sap.ui2.srvc.contracts.refresh"); jQuery.sap.require("sap.ui2.srvc.contracts.searchProvider"); jQuery.sap.require("sap.ui2.srvc.contracts.url");

// Require sap.ui2.srvc.factory (for the Factory) jQuery.sap.require("sap.ui2.srvc.factory");

Determining the Page Name

This step is specific to each client-side page builder. In the following example, the page ID is retrieved from a URL parameter called "page". If no page ID is specified, a hard-coded value is used.

SAPUI5 offers a helper function to access URI parameters.

344 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The following code illustrates how to use this helper function. It includes a hard-coded default page name. Remember to change or remove the hard-coded default page name.

var sPageId = jQuery.sap.getUriParameters().get("page") || "_CHANGE_THIS_DEFAULT_";

Initializing the Factory and PBS Facade

In this step you set up the communication to the page building service using the OData protocol. You do not have to worry about OData details. The communication is wrapped in a service facade called sap.ui2.srvc.PageBuildingService.

For more information, see Class sap.ui2.srvc.PageBuildingService.

Upon creation, the service needs the URI of the OData service. Additionally, you should provide a default error handler that will be called each time there is an error in back-end communication.

For simplicity, you can also pass these parameters to a special method for creating the factory (sap.ui2.srvc.createFactory()), which reduces your code to the following:

function defaultError(sText) { alert(sText); } var oFactory = sap.ui2.srvc .createFactory("/sap/opu/odata/UI2/PAGE_BUILDER_PERS/", defaultError);

In this example, the PBS URI is an absolute path - no protocol, host, or port has been specified. This requires that the OData service communicates with the same server from which the page builder Web application has been loaded. This is necessary for the following reasons:

● All OData requests to the page building service are sent using an XMLHttpRequest.● The code remains valid when transported to another server, for example, from a development system to a

test system and then to a productive system.

NoteIf the HTML resources and the OData service reside on different servers, a reverse proxy is needed due to browsers' "same origin policy".

Due to protection from cross-site request forgery (CSRF) attacks in SAP NetWeaver Gateway, the first operation issued on this PBS facade must be a read operation. Read operations acquire a token, which has to be sent with every write (create, update, or delete) operation. If you create a page using the factory provided by SAP NetWeaver user interface services, the page data is loaded using the PBS facade implicitly, which ensures that this requirement is met.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 345

Loading the Page Data

The page information is maintained in an object called sap.ui2.srvc.Page. Your task is to create such a wrapper instance and call its load function. This can be achieved easily through sap.ui2.srvc.Factory#createPage():

function onSuccess() { } oPage = oFactory.createPage(sPageId, onSuccess);

The factory method createPage requires the ID of the page to be created. It synchronously returns a stub page object that still has to completely load its data from the page building service.

This is done by the load function, which works asynchronously: it sends an OData request for the page data and returns. Later, when the page loading has finished, the success callback handler is called back (in the example above: onSuccess). Similarly, there is another callback if there is an error during page load.

If you provide a success handler to the factory method, the load function will be called automatically. You can supply specialized error handlers for each such call. If you do not provide specialized error handlers, the default error handler from the page building service facade is used (in the example above: defaultError).

Layout

This example uses SAPUI5 and its sap.ui.commons.layout.VerticalLayout to arrange the UIs of all CHIP instances in a single column, one below the other. A vertical layout control is created with default properties and placed into the body of the Web page. The reference to this control is passed to the success handler for page loading.

When the page is created, the layout is bound to the success handler using the standard EcmaScript 5 Function.prototype.bind() method.

Note that the onSuccess handler in the example needs access to the SAPUI5 layout control that is used to arrange the CHIP instance's UIs. The page object is provided as an additional parameter when the success handler is invoked by the load function.

function onSuccess(oLayout, oPage) { }

var oLayout = new sap.ui.commons.layout.VerticalLayout(), oPage = oFactory.createPage(sPageId, onSuccess.bind(null, oLayout));

oLayout.placeAt("canvas");

Success Handler

When the success function that you implicitly passed to sap.ui2.srvc.Page.load is called, the page has been loaded completely and you now can use the page data using the previously created sap.ui2.srvc.Page instance. Note that this instance is also passed as an argument to the success handler.

346 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The example code iterates over all CHIP instances contained on that page. They are wrapped as sap.ui2.srvc.ChipInstance objects. Each of these CHIP instances is asked for its SAPUI5 control tree using getImplementationAsSapui5 and the resulting SAPUI5 control is added to to the vertical layout.

1.2.2.2.2 CHIP Instance Title

A client-side page builder is expected to display and maintain a title for each CHIP instance (sap.ui2.srvc.ChipInstance). This title can be read using getTitle() and written using setTitle(sTitle, true).

function onTitleChange(oTitleControl, oChipInstance) { oTitleControl.setText(oChipInstance.getTitle()); } function onSuccess(oLayout, oPage) { var aChipInstances = oPage.getChipInstances(), i, n, oChipInstance, oTitleControl; for (i = 0, n = aChipInstances.length; i < n; i += 1) { oChipInstance = aChipInstances[i]; oTitleControl = new sap.ui.commons.TextView({ text: oChipInstance.getTitle() }); oChipInstance.attachTitleChange(onTitleChange.bind(null, oTitleControl)); oLayout.addContent(oTitleControl) .addContent(oChipInstance.getImplementationAsSapui5()); } }

NoteThe example code above does not yet support editing of the title. However, it already uses the callback mechanism of the ChipInstance class on title changes. Therefore, if you later add an API allowing the CHIP to change its own title, this will not require any change in the page builder.

For more information, see Class sap.ui2.srvc.ChipInstance.

1.2.2.2.3 Supporting Full Screen Display

The purpose of this example is to show how the integration between the page builder and a CHIP works.

This example does not show the implementation of the fullscreen contract.

Each ChipInstance has a fullscreen flag. If this flag is set, the respective CHIP is the only visible CHIP within the page builder, occupying all available space for CHIPs.

Both the page builder and the CHIP can get and set this flag. The page builder must ensure that it is set for one CHIP only. To do this, the page builder has to attach a listener at each of its ChipInstances, which is called when the fullscreen flag is changed.

function onFullscreen(oChipInstance) { // TODO fullscreen handling

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 347

} function onSuccess(oLayout, oPage) { var aChipInstances = oPage.getChipInstances(), i, n, oChipInstance, oTitleControl; for (i = 0, n = aChipInstances.length; i < n; i += 1) { oChipInstance = aChipInstances[i]; oTitleControl = new sap.ui.commons.TextView({ text: oChipInstance.getTitle() }); oChipInstance.attachFullscreen(onFullscreen.bind(null, oChipInstance)); oLayout.addContent(oTitleControl) .addContent(oChipInstance.getImplementationAsSapui5()); } }

1.2.2.2.4 Supporting Refresh

To refresh a CHIP instance, you can use the refresh() method in a page builder. The attachRefresh(fnEventHandler) method of the refresh contract allows a CHIP instance to attach a listener to the refresh event.

If a CHIP instance has attached a listener, it handles the refresh event on its own in a suitable way, for example, by refreshing the data that it currently displays.

CHIP instances that have not attached a listener can be identified from the return value of the refresh() method. You can recreate such CHIPs to force a refresh. The page builder must trigger the refresh.

1.2.2.2.5 Storing Page-Specific Settings

This topic describes different possibilities to store page-specific settings.

Settings can be stored in the following scopes:

● Personalization: User-specific settings (These settings supersede Customizing and Configuration settings.)● Customizing: Client-specific settings (These settings supersede Configuration settings, but can be

superseded by Personalization settings.)● Configuration: System-wide settings (These settings can be superseded by Customizing and Personalization

settings.)

A page builder can store page-specific settings in the following locations:

● In properties of the page or a CHIP instance itself● In a property bag that is assigned to the page or to a CHIP instance

Depending on the use case, you can decide which of these locations is more appropriate.

348 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Storing Settings in Page or CHIP Instance Properties

A page builder can store page-specific settings in the following locations:

● In the layout property of the page object● In the layoutData property of a CHIP instance object

These properties are stored with the page or CHIP instance.

If you want to store more than one value in the layout or layoutdata property, you have to encode these values (for example, JSON.stringify()). Note that there is no merge mechanism for single attributes across different scopes.

For example, if you create a page or a CHIP instance in the Configuration scope and then modify the page or CHIP instance in the Customizing or Personalization scope, the system creates a copy of the page or CHIP instance as well as the layout or layoutdata property. If you then change the property in the Configuration scope again, these changes will not become visible in the higher scope where you modified the page or CHIP instance.

Storing Settings in Property Bags

Property bags support merging of properties across different scopes.

For example, if you define the properties A, B and C in the Configuration scope and then modify property A in the Customizing or Personalization scope, the properties B and C will remain visible in that scope.

NoteProperty bags that are assigned to CHIP instances can also be accessed from CHIPs. If a page builder uses property bags for CHIP instances, make sure to avoid naming collisions for the names of property bags. We recommend that you use a page builder namespace as a prefix in the name of property bags that you use for page instances.

Related Information

Persisting Settings in Property Bags [page 350]You can use property bags to persist any key-value pairs in order to store settings for your application.

Accessing the CHIP API and the contracts [page 335]

1.2.2.2.6 Catalog Pages

Using catalog pages, content administrators can assign CHIPs to a catalog by simply adding them to a page that is then used as a catalog.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 349

In order to use a page as a catalog, you have to create items of type Catalog Provider in the role menu for the respective users in Role Maintenance (PFCG).

The catalogs that you have created in this way can be retrieved using the getAllCatalogs() method. You can call this method on any page instance (typically on a page that does not act as a catalog). This method returns an sap.ui2.srvc.AllCatalogs collection, which is initially a stub. You have to load this collection using the load() method before you can access the getCatalogs method to get the list of catalogs. Note that this methods only returns catalogs that have been created using catalog pages as described above.

1.2.2.2.7 API Reference

You can find the JSDocs for page building at the following locations:

Namespace sap.ui2.srvc

Class sap.ui2.srvc.Bag

Class sap.ui2.srvc.Catalog

Class sap.ui2.srvc.Chip

Class sap.ui2.srvc.ChipDefinition

Class sap.ui2.srvc.ChipInstance

Class sap.ui2.srvc.Error

Class sap.ui2.srvc.Factory

Class sap.ui2.srvc.Page

Class sap.ui2.srvc.PageBuildingService

1.2.2.3 Persisting Settings in Property Bags

You can use property bags to persist any key-value pairs in order to store settings for your application.

Using property bags, you can persist page settings in the following scopes:

● Personalization: User-specific settings (These settings supersede Customizing and Configuration settings.)● Customizing: Client-specific settings (These settings supersede Configuration settings, but can be

superseded by Personalization settings.)● Configuration: System-wide settings (These settings can be superseded by Customizing and Personalization

settings.)

ExampleThe following example page shows a test application that stores a single property (count) in a bag in order to count from 0 to 100 while saving intermediate results.

An interval timer is used with a delay of 10 milliseconds. The purpose of this interval timer is to simulate user events which trigger the need for saving a property to a bag. The timer calls step(oBag) with the appropriate

350 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

bag, increments the count property by one and requests a save operation. In order to avoid consuming too many resources in the browser and in the back-end system, we stop after counting to 100.

The following example uses an existing page named ZOO and a property bag that is attached to this page and named TODO. Before testing this example, you have to create a page and change the name of the page accordingly in the code below. Also adapt the name of the bag as required.

<!DOCTYPE html><!-- Copyright (c) 2013 SAP AG, All Rights Reserved --><html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=9"/> <title>Personalization Service HOW-TO</title>

<!-- TODO remove data-sap-ui-loglevel for productive usage! --> <script id="sap-ui-bootstrap" data-sap-ui-loglevel="INFO" src="/sap/public/bc/ui5_ui5/resources/sap-ui-core.js"> </script>

<script src="/sap/public/bc/ui2/services/sap/ui2/srvc/bag.js"></script> <script src="/sap/public/bc/ui2/services/sap/ui2/srvc/error.js"></script> <script src="/sap/public/bc/ui2/services/sap/ui2/srvc/factory.js"></script> <script src="/sap/public/bc/ui2/services/sap/ui2/srvc/page.js"></script> <script src="/sap/public/bc/ui2/services/sap/ui2/srvc/pbs.js"></script> <script src="/sap/public/bc/ui2/services/sap/ui2/srvc/utils.js"></script>

<script type="text/javascript"> "use strict"; /*global alert, clearInterval, jQuery, sap, setInterval */ var oFactory, oIntervalId, oPageBuildingService, sPageId = "ZOO", //TODO choose your page ID sUrl = "/sap/opu/odata/UI2/PAGE_BUILDER_PERS/";

/** * Dummy error handler using alert(); change this for productive use! * * @param {string} sMessage */ function onError(sMessage) { alert(sMessage); }

/** * Save the given bag, either immediately or later on, as soon as saving is possible again. * * @param {sap.ui2.srvc.Bag} oBag */ function save(oBag) { var sProperty;

if (oBag.$saving) { oBag.$dirty = true; return; }

sProperty = oBag.getProperty("count"); oBag.$saving = true; oBag.save( function () { oBag.$saving = false; jQuery.sap.log.info("You have been saved", sProperty);

if (oBag.$dirty) {

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 351

oBag.$dirty = false; save(oBag); } }, function (oMap) { oBag.$saving = false; alert(JSON.stringify(oMap)); } ); }

/** * Do one step of incrementing the count. * * @param {sap.ui2.srvc.Bag} oBag */ function step(oBag) { var sProperty = oBag.getProperty("count"), iProperty = parseInt(sProperty, 10);

if (iProperty < 100) { // increment count and save it iProperty += 1; oBag.setProperty("count", String(iProperty)); save(oBag); } else { // stop counting, be nice to the backend ;-) clearInterval(oIntervalId); } }

/** * Page wrapper has been created, start counting from 0. * * @param {sap.ui2.srvc.Page} oPage */ function onPageCreated(oPage) { var sBagId = "TODO", oBag = oPage.getBag(sBagId);

oBag.setProperty("count", "0"); oIntervalId = setInterval(step.bind(null, oBag), 10); }

oPageBuildingService = new sap.ui2.srvc.PageBuildingService(sUrl, onError); oFactory = new sap.ui2.srvc.Factory(oPageBuildingService); oFactory.createPage(sPageId, onPageCreated, onError, true); // flow continues in onPageCreated() </script> </head> <body> This page is intentionally left blank. </body></html>

The main code creates a new sap.ui2.srvc.PageBuildingService with a base URL and an error handler. Depending on the base URL, the settings are read from and written to one of the following scopes:

Base URL Description

/sap/opu/odata/UI2/PAGE_BUILDER_PERS/ User-specific personalization

/sap/opu/odata/UI2/PAGE_BUILDER_CUST/ Client-specific customizing

/sap/opu/odata/UI2/PAGE_BUILDER_CONF/ System-wide configuration

352 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Then, a sap.ui2.srvc.Factory is created based on the page building service, and createPage is called in order to create a page wrapper object with a specific ID. The data for the page is loaded from the page building service. Upon success or failure of this backend call, the corresponding handler function is invoked. The last parameter to createPage() makes sure that only the needed parts of the page are loaded, including all its bags, but excluding any embedded CHIP instances.

Once the page data has been loaded, getBag() is called on the page wrapper to access a certain bag, creating it if needed. On the bag, setProperty() is called to set the value of a property, again creating it if needed. Note that the property value is a string and needs to be converted.

Saving a Property Bag

The save() method must not be called on a bag while a previous save() operation is still running. It is up to the application to deal with this.

In the example above, it is not required to store each increment of the counter individually. It is sufficient to store the intermediate result now and then, and to make sure that the result is properly stored at the end. This is achieved in the following way: Like any JavaScript object, an sap.ui2.srvc.Bag instance can be augmented with additional properties. The example above uses a $ prefix to avoid collisions with possible future enhancements of the sap.ui2.srvc.Bag class.

The save(oBag) method in the example above keeps track of two states on the level of individual bags:

● It needs to know whether a save() operation is currently running.● It needs to remember the calls which could not trigger an immediate save() operation.

If a save operation could not be triggered immediately, the bag is marked as $dirty and needs to be saved later, at the earliest opportunity.

In the example above, we intentionally do not trigger another save() operation in case of failure. However, this needs to be decided case-by-case for each implementation. In case of success, the $dirty flag is checked, and another save() operation is triggered if needed.

The jQuery.sap.log.info() call adds some logging to the browser's console. Note that it remembers the intermediate result at the moment the save() method is invoked - this is usually different from the current state at the time the operation has finished.

Related Information

Storing Page-Specific Settings [page 348]This topic describes different possibilities to store page-specific settings.

Accessing the CHIP API and the contracts [page 335]

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 353

1.2.2.4 Embedding an Application into a Shell

The shell API provides functionality for embedding JavaScript-based applications into a shell.

The shell API provides the following functionality:

● Abstraction from the environment where the JavaScript code is executed● Trigger navigation to a launchpad URL● Add a search provider in NWBC for Desktop 4.0● Propagation of user-specific settings from the back-end system to SAPUI5

Abstraction

The shell API provides functions for navigation and search in JavaScript-based applications that can run in different environments:

● A shell, like SAP NetWeaver Business Client or SAP NetWeaver Portal● Directly in a Web browser

Applications can use this API to trigger shell-related functionality, such as navigation.

The shell API provides an abstraction from the environment where the JavaScript code is executed. If you use the shell API, the system adapts its behavior depending on the the environment where the code is executed.

ExampleFor example, you can create a page with a launchpad link that starts an ABAP transaction (see method navigateToUrl below). If a user clicks this link in NWBC for Desktop, the transaction is displayed in SAPGUI for Windows (if SAPGUI for Windows is installed on the client PC). If a user clicks the same link on a standalone page in a Web browser, the transaction is displayed in SAPGUI for HTML.

Methods

The shell API provides the following methods:

Method Description Supported Environments

navigateToUrl Allows you to navigate to the target of a URL.

The following types of URLs are supported:

● Absolute and relative HTTP(S) URLsAbsolute URLs must start with http:// or https://.

NWBC for Desktop 4.0

SAP NetWeaver Portal

Standalone page in Web browser

354 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Method Description Supported Environments

Relative URLs must start with /, ./, or ../.

NoteFor absolute and relative HTTP(S) URLs, only GET requests are supported.

● Launchpad URLsLaunchpad URLs must start with sap-lpd.Launchpad URLs point to launchpad applications that are defined in transaction LPD_CUST.Lauchpad applications of the following types are supported:

○ URL○ Object-Based Navigation

addSearchProvider Allows you to programatically add a search provider in SAP NetWeaver Business Client.

This method has neutral behavior (null object pattern) if it is run in an environment that is not supported (for example, in a standalone page in a Web browser).

NWBC for Desktop 4.0

Propagating Settings to SAPUI5

The shell API reads user-specific settings from the back-end system and propagates these to SAPUI5.

The following settings are read from the back-end system:

● Decimal Notation● Date Format● Time Format

In the back-end system, users can change these settings by choosing System User Profile Own DataDefaults .

In an NWBC 4.0 Desktop environment, users select a language on the logon screen. In a Portal environment, users can select a language by choosing PersonalizePortal.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 355

Table 3:Setting Example Description

Language en_US In an NWBC 4.0 Desktop environment, users select a language on the logon screen.

In a Portal environment, users can select a language by choosing PersonalizePortal.

You can override the language by using the URL parameter sap-language.

RTL false Indicates right-to-left writing direction.

ABAP number format -1.234.567,89 This format is read from the back-end system.

ABAP date format 13.01.2013 This format is read from the back-end system.

ABAP time format 14:32:29 This format is read from the back-end system.

Related Information

Basic URIs [page 364]

1.2.2.4.1 API Reference

You can find the JSDocs for the shell API at the following locations:

Namespace NavigationHandle

Namespace sap.ui2.shell

Class sap.ui2.srvc.Error

Namespace sap.ui2.srvc.log

Namespace SearchHandle

356 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.2.5 Using SAP NetWeaver User Interface Services in SAPUI5 Applications

This code example shows how to run a SAPUI5 application in a shell with the settings of the user who is currently logged on, like language, date, time and number formats, and theme.

SAP NetWeaver user interface services reads the user settings from the back-end system and provides them to the SAPUI5 application.

The following code example shows how you can implement this:

<!DOCTYPE html><!-- Copyright (c) 2013 SAP AG, All Rights Reserved --><html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <title>A SAPUI5 Application Using SAP NetWeaver User Interface Services</title>

<script src="/sap/public/bc/ui2/shell-api/sap/ui2/shell/shell.js"></script>

<script id="sap-ui-bootstrap" src="/sap/public/bc/ui5_ui5/resources/sap-ui-core.js"> </script>

<script type="text/javascript"> "use strict"; /*global jQuery, sap */

sap.ui.getCore().attachInit(function () { jQuery.sap.includeStyleSheet("./styles/override_sapui5_styles.css");

//TODO add your application code here! }); </script> </head> <body class="sapUiBody" role="application"> <div id="canvas"></div> </body></html>

The first step is to include shell.js before the SAPUI5 bootstrap. This is necessary because shell.js hooks into SAPUI5's bootstrap process, retrieves the user's settings from the back-end system, and applies them to SAPUI5 just before the bootstrap finishes. This makes sure that all files that depend on these settings, like translatable texts or style sheets, are loaded only once, with the right settings.

The next step is to make sure that your application code does not run before SAPUI5's core has been initialized. Use sap.ui.getCore().attachInit() for this purpose. This approach makes sure that all objects that depend on user settings, like date, time, or number formats, are created with the user's preferred format (because they are not created before these settings take effect).

This bootstrap sequence has a side effect: If you want to override style classes, you cannot do this by including your stylesheets directly from the HTML page. This is because the standard SAPUI5 stylesheets are included after the page has loaded completely. If you want to include your own stylesheets, you can use jQuery.sap.includeStyleSheet() as shown in the code above.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 357

NoteIncluding this file automatically performs domain relaxation (in the same way as Web Dynpro) and there is no way to influence its behavior. In most cases this is exactly what you need.

NoteIf you analyze your application's performance, note that retrieving the user's settings from the back-end system requires an HTTP GET request. This request takes place in parallel with the SAPUI5 bootstrap (which typically is cached) and sequentially before all requests that are sent by the application.

1.2.2.6 Creating an Application Shell

This section describes how to create an application shell that retrieves system information, user information and a user menu from a back-end system using the start-up service. When you integrate SAPUI5 applications into this shell, you can easily propagate user-specific settings retrieved from the back-end system to your SAPUI5 applications.

An application shell is an SAPUI5 application that provides the following capabilities:

● Allow users to log on to a back-end system● Display system information and user-related information that has been read from the back-end system● Display a user menu as defined in the logon system● Allow users to navigate in the menu and open applications in the shell's content area● Propagate user-specific settings that have been read from the back-end system to SAPUI5 applications that

have been started in the content area

1.2.2.6.1 Accessing information from a back-end system

The JavaScript start-up API allows you to read the following information from a back-end system:

● User information (for example user name, e-mail address)● Information on the user's logon system● The user menu

NoteThe back-end service that is called by the JavaScript API may change in future support packages, but the JavaScript API will remain stable.

In order to use the JavaScript API, you have to include the following scripts:

<script src="/sap/public/bc/ui2/services/sap/ui2/srvc/error.js"></script><script src="/sap/public/bc/ui2/services/sap/ui2/srvc/utils.js"></script> <script src="/sap/public/bc/ui2/shell-api/sap/ui2/shell/startup.js"></script>

358 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.2.6.2 URL Parameters for Back-End Authentication

When you start the application shell, you can use URL parameters to specify a client and a language for the logon screen.

The following URL parameters are supported:

Table 4:URL Parameter Description

sap-client The client for logon at the back-end system

sap-language The language for logon at the back-end system

1.2.2.6.3 Accessing System and User Information

The following example outlines how you can access system information and user information:

var oUser = sap.ui2.shell.getUser();

oUser.load( { depthAtRoot: 2, nodeId: "FOO~Z_ACME_BAR:42", depthAtNode: 1 }, function() { /* success handler: access user data */ }, function(sErrorMessage) { /* failure handler: e.g. display load error */ } );

The load() method that is called on the user object reads data from the back-end system asynchronously. This means that you should process further data in the success handler provided to the load() method.

The JavaScript start-up API logs any errors occuring during load to the browser console. In the failure handler, you may for example display an error message on the screen based on the error message provided.

The user object remains a stub until the load() method has finished with success. You can check whether the object is still a stub using oUser.isStub().

Once the load has been completed successfully, you can access various information related to the user and the logon system. The following list shows the accessor methods available:

// user logon informationoUser.getSystem()oUser.getClient()oUser.getId()

// user attributesoUser.getFirstName()oUser.getLastName()oUser.getFullName()oUser.getEmail()oUser.getTimeZone()oUser.getWelcomeMessage()

// user

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 359

oUser.getLanguage()oUser.isRtl()oUser.getDateFormat()oUser.getNumberFormat()oUser.getTimeFormat()

For more information, see the JavaScript Docs.

1.2.2.6.4 Propagating Settings to SAPUI5

The following code example shows how you can propagate user settings to an SAPUI5 application.

You would typically insert such code into your controller's onInit() method.

var oUser = sap.ui2.srvc.getUser();

oUser.load( { depthAtRoot: 2, nodeId: "FOO~Z_ACME_BAR:42", depthAtNode: 1 }, function () { var oFormatSettings = sap.ui.getCore().getConfiguration().getFormatSettings();

oFormatSettings.setLegacyNumberFormat(oUser.getNumberFormat()); oFormatSettings.setLegacyDateFormat(oUser.getDateFormat()); oFormatSettings.setLegacyTimeFormat(oUser.getTimeFormat()); }, function (sError) { // failure handler } );

NoteMake sure that you do not create any objects relying on formatting options before the configuration has the correct values. This applies to resource bundles, number formatters, date formatters and time formatters.

1.2.2.6.5 Accessing Menu Information

After a successful execution of the load() method, you can access the user's menu using oUser.getMenu().getEntries().

In the array that is returned, each entry represents either a folder or an application. You can check this using oEntry.isFolder().

Folders as well as applications have an identifier (oEntry.getId()) and a language-dependent text (oEntry.getText()).

For folders, you can get the array of children using oEntry.getChildren().

360 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

For applications, you can get the application type using oEntry.getType() and the URL using oEntry.getUrl().

http://help.sap.com/javadocs/ui-services/shell-api/symbols/sap.ui2.shell.Menu.html

For more information, see the JSDocs on Class sap.ui2.shell.Menu.

1.2.2.6.6 Displaying the Complete Menu Tree

The SAPUI5 shell control allows you to add tool popups to its left border.

For more information on the SAPUI5 shell control, see the control documentation for the SAPUI5 demo kit ( UX3 Controls Shell ).

You can add such a tool popup to your shell to display a tree representing the user's complete menu. We recommend to make the popup modal and react on its “open” event to lazily create the tree's content.

Shell.view.xml<Shell> <toolPopups> <ToolPopup icon="..." iconHover="..." id="navigationToolPopup" modal="true" open="onNavigationToolPopupOpen" title="{i18n>navigation}"> </ToolPopup> </toolPopups></Shell>

In order to structure the content of the popup, you can use a view. You should pass the user object (sap.ui2.shell.getUser()) to it, as it is initially a stub and the menu cannot be accessed immediately. This gives your shell the chance to asynchronously load the user object, so it will be available in time for the user to open the tool popup.

In order to get informed about selection changes, you need to pass a callback to the view. This allows you to keep the menu item selection in the shell in sync with the one in the tree.

Shell.controller.js /** * Initialization. */ onInit: function () { this.oUser = sap.ui2.shell.getUser(); this.oNavigationView = sap.ui.view({ type: "XML", viewData: { selected: function (oNode) { // ... this.getView().byId("navigationToolPopup").close(); }, user: this.oUser // only Menu is needed, but User is still a stub! }, viewName: "...Navigation" }); this.getView().byId("navigationToolPopup").addContent(this.oNavigationView); this.oUser.load(...);

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 361

},

/** * Event handler for the navigation tool popup's "open" event. */ onNavigationToolPopupOpen: function () { this.oNavigationView.getController().onOpen(); },

In the navigation tree, we recommend using a tree control. You may want to remove its header (showHeader="false"). Wrap the menu's folders and applications into the tree nodes as shown in the example below:

Navigation.controller.js

/** * Wraps the given menu entries as tree nodes and adds those to the given parent. * * @param {sap.ui.commons.Tree|sap.ui.commons.TreeNode} vParent * either a tree or a tree node * @param {sap.ui2.shell.Node[]} aEntries * a list of menu entries */ buildTree: function (vParent, aEntries) { var oEntry, oTreeNode, i, n;

for (i = 0, n = aEntries.length; i < n; i += 1) { oEntry = aEntries[i]; oTreeNode = new sap.ui.commons.TreeNode({ expanded: false, hasExpander: oEntry.isFolder(), selected: this.onTreeNodeSelected.bind(this, oEntry), text: oEntry.getText() }); vParent.addNode(oTreeNode); this.oTreeNodeById.put(oEntry.getId(), oTreeNode); if (this.oInitiallySelectedNode === oEntry) { selectTreeNode(oTreeNode); }

if (oEntry.isFolder()) { this.buildTree(oTreeNode, oEntry.getChildren()); } } },

/** * Initialization. */ onInit: function () { this.oInitiallySelectedNode = null; // because selection happens already before opening this.oTreeNodeById = new sap.ui2.srvc.Map(); },

/** * Called by the embedding tool popup whenever it opens. */ onOpen: function () { var aEntries = this.getView().getViewData().user.getMenu().getEntries(), oTree = this.getView().getContent()[0];

362 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

if (oTree.getNodes().length === 0) { // lazily build tree this.buildTree(oTree, aEntries); } },

/** * Event handler for any tree node's "selected" event. * * @param {sap.ui2.shell.Node} oEntry * @param {sap.ui.base.Event} oControlEvent */ onTreeNodeSelected: function (oEntry, oControlEvent) { this.getView().getViewData().selected(oEntry); },

/** * Selects the menu entry represented by the given node. * * @param {sap.ui2.shell.Node} oNode */ selectNode: function (oNode) { var oTreeNode = this.oTreeNodeById.get(oNode.getId()); if (oTreeNode) { selectTreeNode(oTreeNode); } else { this.oInitiallySelectedNode = oNode; } }

In the example above, some details have been omitted, for example selecting a tree node with oTreeNode.select(true).

The example illustrates how you can use a node's ID to uniquely identify it, for example in hash maps. You may want to use the same ID in the URL to keep state in the URL. Node objects are passed between the shell view and the navigation view to identify the current selection.

1.2.2.6.7 API Reference

You can find the most important JSDocs for creating an application shell at the following locations:

Method getUser() in namespace sap.ui2.shell

Class sap.ui2.shell.User

Class sap.ui2.shell.Menu

1.2.3 OData Services

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 363

1.2.3.1 Launchpad Service

The launchpad service allows you to retrieve content from launchpads in your backend systems using OData URI conventions.

The content of lauchpads is maintained in transaction LPD_CUST in your backend system.

For more information on launchpads, see the SAP NetWeaver documentation at http://help.sap.com/netweaver SAP NetWeaver Platform Application Help Function-Oriented View Application ServerApplication Server ABAP UI Technologies in ABAP Launchpads .

1.2.3.1.1 Displaying the Service Definition XML

You perform the following steps on your SAP NetWeaver Gateway server.

1. In the SAP NetWeaver Customizing, choose SAP NetWeaver Gateway OData Channel AdministrationGeneral Settings Maintain Services .

2. Search for the external name LAUNCHPAD.3. Select the launchpad service to display the available ICF nodes.4. Make sure that the ODATA ICF node is active and that a system alias for your backend system is maintained.5. Select the ODATA ICF node, and click Call Browser.6. If you are prompted for your credentials, enter your user ID and password for the SAP NetWeaver Gateway

system.

The service definition XML is displayed in your browser.

The browser's URL field displays the service root URI. It should look similar to the following:

http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/?$format=xml

NoteIf a system alias for your system has been maintained, but is not selected as default, you can either edit the configuration or extend the URL by adding ;o=<system_alias> after the service name. For example, for system ABC and client 123, the URL could be as follows:

http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD;o=ABC_123/?$format=xml

1.2.3.1.2 Basic URIs

Service Root URI

The service root URI for the launchpad service contains the server, port and service name, for example as follows:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/

364 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteThe URI above is used in all examples in this section of the documentation. To reproduce the examples in the documentation, you have to replace <server> and <port> by the server and port of your SAP NetWeaver Gateway system.

For more information on how to find out your root service URI, see Displaying the Service Definition XML [page 364].

Service Document

You get the service document by adding the URL parameter ?$format=xml to the service root URI.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/?$format=xml

Metadata Document

To get the metadata document, add $metadata to the service root URI.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/$metadata

Navigating in the Service Document

For your convenience, if you add the URL parameter sap-ds-debug=true, the hrefs in the document are displayed as links. This allows you to easily navigate in the document structure.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/?$format=xml&sap-ds-debug=true

1.2.3.1.3 Examples for Basic Service Requests

You can extend the service root URI manually to execute different requests of the launchpad service and check the results.

The examples in this section show some basic OData requests.

Prerequisites

In order to reproduce these examples in your system, the following prerequisites must be met:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 365

● Launchpads need to be customized in your backend system.You can display the Customizing of launchpads in transaction LPD_CUST.For more information on the Customizing of launchpads in the backend system, see the SAP NetWeaver Library at http://help.sap.com/netweaver SAP NetWeaver Platform Application Help SAP NetWeaver Library: Function-Oriented View Application Server Application Server ABAP UI Technologies in AS ABAP Launchpads .

● The launchpad service needs to be activated on the SAP NetWeaver Gateway server.For more information, see the User Interface Add-on for SAP NetWeaver Installation Guide at http://help.sap.com/netweaver User Interface Add-on for SAP NetWeaver User Interface Add-on for SAP NetWeaver Installation Guide .

List of all Launchpads

If you add Folders to the path in the service URL, this request retrieves a list of all folders, including all top-level folders. Each top-level folder represents a launchpad.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders?$format=xml

The XML code returned by the server contains an <entry> element for each folder.

ExampleThe following XML code shows an example for a folder entry that represents a launchpad:

<?xml version="1.0" encoding="utf-8" ?><feed xml:base="http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders</id> <title type="text">Folders</title> <updated>2012-07-19T15:27:14Z</updated> <author> <name /> </author> <link href="Folders" rel="self" title="Folders" /> <entry> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')</id> <title type="text">Folders('08HOME_AND09AREA_PAGE00')</title> <updated>2012-07-17T15:24:26Z</updated> <category term="LAUNCHPAD.Folder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link href="Folders('08HOME_AND09AREA_PAGE00')" rel="edit" title="Folder" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/Folders" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Folders" type="application/atom+xml;type=feed" title="Folders" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/Links" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Links" type="application/atom+xml;type=feed" title="Links" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/DefaultLink" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/DefaultLink" type="application/atom+xml;type=entry" title="DefaultLink" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/AllLinks" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AllLinks"

366 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

type="application/atom+xml;type=feed" title="AllLinks" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/Icons" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Icons" type="application/atom+xml;type=feed" title="Icons" /> <content type="application/xml"> <m:properties> <d:id>08HOME_AND09AREA_PAGE00</d:id> <d:hidden>false</d:hidden> <d:text>Home and Area Page</d:text> <d:description>Home and Area Page</d:description> <d:level>1</d:level> <d:style /> <d:applicationAlias /> </m:properties> </content> </entry>

If you search for <d:text> on this level, you will find the names of your launchpads.

Note the ID of the folder:

<id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')</id>

The folder ID contains the launchpad ID 08HOME_AND09AREA_PAGE00.

Every launchpad is identified by the combination of a role name and an instance name. In the example above, the role name is HOME_AND, and the instance name is AREA_PAGE.

Root folder of a Launchpad

If you enter the ID of a folder in the URL field of your browser, this retrieves a single folder.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')?$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')?$format=xml

ExampleThe following XML code shows an example for a launchpad:

<?xml version="1.0" encoding="utf-8" ?><entry xml:base="http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')</id> <title type="text">Folders('08HOME_AND09AREA_PAGE00')</title> <updated>2012-07-17T15:24:26Z</updated> <category term="LAUNCHPAD.Folder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link href="Folders('08HOME_AND09AREA_PAGE00')" rel="edit" title="Folder" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/Folders" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Folders" type="application/atom+xml;type=feed" title="Folders" />

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 367

<link href="Folders('08HOME_AND09AREA_PAGE00')/Links" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Links" type="application/atom+xml;type=feed" title="Links" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/DefaultLink" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/DefaultLink" type="application/atom+xml;type=entry" title="DefaultLink" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/AllLinks" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AllLinks" type="application/atom+xml;type=feed" title="AllLinks" /> <link href="Folders('08HOME_AND09AREA_PAGE00')/Icons" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Icons" type="application/atom+xml;type=feed" title="Icons" /> <content type="application/xml"> <m:properties> <d:id>08HOME_AND09AREA_PAGE00</d:id> <d:hidden>false</d:hidden> <d:text>Home and Area Page</d:text> <d:description>Home and Area Page</d:description> <d:level>1</d:level> <d:style /> <d:applicationAlias /> </m:properties> </content></entry>

The <d:level> tag indicates the hierarchy level of the folder. Level 1 indicates that this folder is the root folder of a launchpad.

NoteIn case you have not found the launchpad you were looking for, for example because the ID was wrong, you can use a statement to get all folders in combination with a filter criterium. For example if you want to search for a launchpad with the name "Home and Area Page", the request URL should contain /Folders?$filter=text eq 'Home and Area Page'.

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders?$filter=text eq 'Home and Area Page'&$format=xml

List of Child Folders of a Launchpad

If you specify a folder's launchpad ID and add /Folders in the URL, you get a list of all child folders of the specified folder.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/Folders?$format=xml

If the folder that you specify is the root folder of a launchpad, you get the a list of all folders that are contained in this launchpad.

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')/Folders?$format=xml

368 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

ExampleThe XML that you receive contains an entry for each child folder of the launchpad's root folder. The following XML code shows an example:

<?xml version="1.0" encoding="utf-8" ?> <feed xml:base="http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders</id> <title type="text">Folders</title> <updated>2012-07-20T08:16:38Z</updated> <author> <name /> </author> <link href="Folders" rel="self" title="Folders" /> <entry> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')</id> <title type="text">Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')</title> <updated>2012-07-20T08:16:38Z</updated> <category term="LAUNCHPAD.Folder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')" rel="edit" title="Folder" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Folders" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Folders" type="application/atom+xml;type=feed" title="Folders" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Links" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Links" type="application/atom+xml;type=feed" title="Links" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/DefaultLink" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/DefaultLink" type="application/atom+xml;type=entry" title="DefaultLink" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/AllLinks" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AllLinks" type="application/atom+xml;type=feed" title="AllLinks" /> <link href="Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Icons" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Icons" type="application/atom+xml;type=feed" title="Icons" /> <content type="application/xml"> <m:properties> <d:id>08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4</d:id> <d:hidden>false</d:hidden> <d:text>Benefits and Payment</d:text> <d:description>Display the plans in which you are currently enrolled, enroll in new benefit plans, and download an enrollment form. Display your salary statement.</d:description> <d:level>2</d:level> <d:style /> <d:applicationAlias /> </m:properties> </content></entry>

You can search the XML code for the name of a folder (a child of your launchpad's root folder).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 369

The following screenshot shows a folder in the Home and Area Page launchpad in transaction LPD_CUST:

The name of the folder (folder text) is Benefits and Payment.

If you search the XML code for Benefits and Payment, you find the following line:

<d:text>Benefits and Payment</d:text>

Note the ID of the folder:

<id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')</id>

The folder ID contains this folder's launchpad ID: 08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4.

NoteIf you reproduce this example in your system, the launchpad ID might be different than in the documentation. In the following examples, use the ID that you find in your system.

List of a Folder's Content

A launchpad folder can contain content of the following types:

● Folders● Links● Icons

ExampleIn the following example, the folder Benefits and Payments contains the two subfolders:

● The folder Benefits, which contains two links● The folder Payments, which contains two links

The following screenshot shows this folder in transaction LPD_CUST:

370 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

NoteThe Benefits and Payments launchpad also contains an Inactive Applications folder. This folder is not exposed in the service document.

To access the folder Benefits and Payments directly, use the following URL:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')?$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')?$format=xml

To access the subfolders of the the folder Benefits and Payments, use the following URL:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/Folders?$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Folders?$format=xml

To access the child links of a folder in a launchpad (in our example, the Benefits and Payments folder in the Home and Area Page launchpad), add /Links to the URL as in the following example:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/Links?$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Links?$format=xml

This returns all links that are direct children of the of the folder that you have specified (excluding links in subfolders).

If you would like to display all links that are contained in a folder including links in any subfolders, add /AllLinks to the URL as in the following example:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/AllLinks?$format=xml

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 371

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/AllLinks?$format=xml

The following XML code shows an example for a link entry:

<?xml version="1.0" encoding="utf-8" ?> <feed xml:base="http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Links</id> <title type="text">Links</title> <updated>2012-07-23T12:04:16Z</updated> <author> <name /> </author> <link href="Links" rel="self" title="Links" /> <entry> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')</id> <title type="text">Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')</title> <updated>2012-07-23T12:04:16Z</updated> <category term="LAUNCHPAD.Link" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')" rel="edit" title="Link" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')/AssociatedApps" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AssociatedApps" type="application/atom+xml;type=feed" title="AssociatedApps" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')/AssociatedLinks" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AssociatedLinks" type="application/atom+xml;type=feed" title="AssociatedLinks" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')/Tags" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Tags" type="application/atom+xml;type=feed" title="Tags" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')/Icons" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Icons" type="application/atom+xml;type=feed" title="Icons" /> <link href="Links('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')/NavTargetStandalone" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NavTargetStandalone" type="application/atom+xml;type=entry" title="NavTargetStandalone" /> <content type="application/xml"> <m:properties> <d:id>08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F</d:id> <d:href>sap-lpd:08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F</d:href> <d:type>URL</d:type> <d:hidden>false</d:hidden> <d:text>Participation Overview</d:text> <d:description>View a list of plans in which you are currently enrolled.</d:description> <d:style /> <d:applicationData /> <d:applicationType>URL</d:applicationType>

372 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

<d:applicationAlias /> <d:myFavorite>false</d:myFavorite> <d:myFavoriteCreated m:null="true" /> <d:myLastUsed m:null="true" /> <d:myUsageCounter>0</d:myUsageCounter> </m:properties> </content> </entry>

To sort this list in ascending order, you can add the URL parameter $orderby=text asc as in the following example:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/AllLinks?$orderby=text asc&$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/AllLinks?$orderby=text asc&$format=xml

To sort this list in descending order, replace asc by desc as in the following example:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/AllLinks?$orderby=text desc&$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/AllLinks?$orderby=text desc&$format=xml

You can also filter the list using simple statements like the following: $filter=text eq 'Participation Overview'

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/AllLinks?$filter=text eq 'Participation Overview'&$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/AllLinks?$filter=text eq 'Participation Overview'&$format=xml

To get the icons of a folder, you can request /Folders('<launchpad ID of the folder>')/Icons as in the following example:

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/Icons?$format=xml

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Icons?$format=xml

The following XML code shows an example for an icon entry:

<?xml version="1.0" encoding="utf-8" ?> <feed xml:base="http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Icons</id> <title type="text">Icons</title> <updated>2012-07-23T12:45:17Z</updated> <author> <name /> </author>

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 373

<link href="Icons" rel="self" title="Icons" /> <entry> <id>http://vmw3815.wdf.sap.corp:50009/sap/opu/odata/UI2/LAUNCHPAD;o=PB8_111/Icons('LARGE08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4xxxx%2FSAP%2FPUBLIC%2FBC%2FPictograms%2Fmoney.gif')</id> <title type="text">Icons('LARGE08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4xxxx%2FSAP%2FPUBLIC%2FBC%2FPictograms%2Fmoney.gif')</title> <updated>2012-07-23T12:45:17Z</updated> <category term="LAUNCHPAD.Icon" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link href="Icons('LARGE08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4xxxx%2FSAP%2FPUBLIC%2FBC%2FPictograms%2Fmoney.gif')" rel="edit" title="Icon" /> <link href="Icons('LARGE08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4xxxx%2FSAP%2FPUBLIC%2FBC%2FPictograms%2Fmoney.gif')/$value" rel="edit-media" type="image/gif" /> <content type="image/gif" src="/SAP/PUBLIC/BC/Pictograms/money.gif" /> <m:properties> <d:id>LARGE08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4xxxx/SAP/PUBLIC/BC/Pictograms/money.gif</d:id> <d:src>/SAP/PUBLIC/BC/Pictograms/money.gif</d:src> <d:mimeType>image/gif</d:mimeType> <d:size>LARGE</d:size> </m:properties> </entry></feed>

Reference of Most Important URL Parts

The following table provides a summary of the most important URL parts for the launchpad service that have been described in this section:

Table 5: URL PartsURL Part Example Description

/Folders http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE00')/Folders?$format=xml

List of folders in a given folder

/Links http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF880C52951503A4')/Links?$format=xml

List of a links in a given folder (excluding links in subfolders)

/AllLinks http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/

List of all links in a given folder, including links in all subfolders

374 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

URL Part Example Description

Folders('<LAUNCHPAD ID>')/AllLinks?$format=xml

/Icons http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/Folders('<LAUNCHPAD ID>')/Icons?$format=xml

List of icons in a given folder

Table 6: URL ParametersParameter Example Description

$orderby=<property> asc $orderby=text asc Sort in ascending order

$orderby=<property> desc $orderby=text desc Sort in descending order

$filter=<property> eq <value>

$filter=text eq 'Participation Overview'

Filter for items with the name 'Participation Overview'

$filter=text eq 'Test and Demos' and level eq 1

Filter for a launchpad with the name 'Test and Demos'

1.2.3.1.4 Service Operations

This section describes the service operations that are exposed by the launchpad service.

The service operations are defined by function imports that you can find in the service metadata document.

LAUNCHPAD/ResolveLink

You can use this service operation to get details for navigation link targets from launchpad Customizing in a format which is adjusted to a js-epcm-navigation and which can be triggered on the user interface.

This service operation has the return type NavTarget. You can use this operation to navigate to a target using JavaScript. The advantages are as follows:

● URLs are only resolved if required.● Triggering the navigation is handled by the UI.● OBN targets can be resolved in the enterprise portal's Portal Content Directory.

URL: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/ResolveLink?linkId='<LAUNCHPAD ID>'&businessParams='<BUSINESS PARAMETERS>'&shellType='<SHELL TYPE>'

Example: http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/ResolveLink?linkId='08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F'&businessParams=''&shellType='STANDALONE'

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 375

TipTo get the response in JSON format, add the URL parameter &$format=json.

Table 7: ParametersParameter Name Type Description

linkId Edm.String Launchpad ID

Example: '08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F'

Alternatively, the linkID can also be composed of the role, instance and application alias.

Example: '09AEPM_DEMO0DEPM_APP_LINKS0010COPY_SALES_ORDER'

In this example, the role is AEPM_DEMO, the instance is EPM_APP_LINKS, and the application alias is COPY_SALES_ORDER.

businessParams Edm.String

shellType Edm.String The following values are supported:

● 'NWBC'● 'STANDALONE'● 'PORTAL'● '' (default)

If no shell type is set, the STANDALONE type is used.

The STANDALONE shell type returns an absolute URL.

ExampleThe following example shows the structure of the data returned for shell type STANDALONE in JSON format:

{

"d": { "__metadata": { "uri": "http://<server>:<port>/sap/opu/odata/UI2/LAUNCHPAD/NavTargets('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')", "type": "LAUNCHPAD.NavTarget" },

376 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

"Absolute": { "__metadata": { "type": "LAUNCHPAD.Absolute" }, "shellTitle": "Participation Overview", "windowFeatures": "", "historyMode": 0, "url": "http://www.sap.com?", "systemAlias": "" }, "Obn": { "__metadata": { "type": "LAUNCHPAD.Obn" }, "businessObject": "", "operation": "", "resolvingMode": "", "getParameters": "", "systemAlias": "" }, "linkId": "08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F", "businessParams": "", "shellType": "STANDALONE", "launchInplace": "false", "shellHosted": "true", "shellVisibility": "MINIMAL", "applicationType": "URL", "applicationData": "", "applicationAlias": "", "postParameters": "" }

}

ExampleThe following example shows the structure of the data returned for shell type NWBC in JSON format:

{

"d": { "__metadata": { "uri": "http://vmw3815.wdf.sap.corp:50009/sap/opu/odata/UI2/LAUNCHPAD/NavTargets('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')", "type": "LAUNCHPAD.NavTarget" }, "Absolute": { "__metadata": { "type": "LAUNCHPAD.Absolute" }, "shellTitle": "Participation Overview", "windowFeatures": "", "historyMode": 1, "url": "ROLES://portal_content/com.sap.pct/every_user/com.sap.pct.erp.common.bp_folder/com.sap.pct.erp.common.roles/com.sap.pct.erp.common.erp_common/com.sap.pct.erp.common.lpd_start_url?RequestMethod=GET&URLTemplate=http%3a%2f%2fwww.sap.com&sap-nwbc-is_suspend_scenario=", "systemAlias": "" }, "Obn": { "__metadata": { "type": "LAUNCHPAD.Obn" }, "businessObject": "", "operation": "",

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 377

"resolvingMode": "", "getParameters": "", "systemAlias": "" }, "linkId": "08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F", "businessParams": "", "shellType": "NWBC", "launchInplace": "false", "shellHosted": "true", "shellVisibility": "MINIMAL", "applicationType": "URL", "applicationData": "", "applicationAlias": "", "postParameters": "" }

}

ExampleThe following example shows the structure of the data returned for shell type PORTAL in JSON format:

{

"d": { "__metadata": { "uri": "http://vmw3815.wdf.sap.corp:50009/sap/opu/odata/UI2/LAUNCHPAD/NavTargets('08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F')", "type": "LAUNCHPAD.NavTarget" }, "Absolute": { "__metadata": { "type": "LAUNCHPAD.Absolute" }, "shellTitle": "Participation Overview", "windowFeatures": "toolbar=no,resizable=yes", "historyMode": 1, "url": "ROLES://portal_content/com.sap.pct/every_user/com.sap.pct.erp.common.bp_folder/com.sap.pct.erp.common.roles/com.sap.pct.erp.common.erp_common/com.sap.pct.erp.common.lpd_start_url?RequestMethod=GET&URLTemplate=http%3a%2f%2fwww.sap.com", "systemAlias": "" }, "Obn": { "__metadata": { "type": "LAUNCHPAD.Obn" }, "businessObject": "", "operation": "", "resolvingMode": "", "getParameters": "", "systemAlias": "" }, "linkId": "08HOME_AND09AREA_PAGE2080E0ED0A31991DDDBF8811D66FDE133F", "businessParams": "", "shellType": "PORTAL", "launchInplace": "false", "shellHosted": "true", "shellVisibility": "MINIMAL", "applicationType": "URL", "applicationData": "", "applicationAlias": "", "postParameters": "" }

378 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 379

1.2.3.1.5 Entity Data Model for Launchpad ServiceEntity Data Model for launchpad service

380 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The launchpad service are based on a Entity Data Model (EDM) that provides the following entities:

● Folders● Links● Icons● Tags

1.2.3.2 POWL Enabling Service

You can expose Personal Object Worklists (POWL) as OData services without writing any code. All steps are performed in Customizing.

The OData services that you create as described below return query results exactly as defined by the corresponding POWL query. These OData services do not currently support any additional functions, like system query options $orderby, $top and $skip. $orderby is used for sorting columns in the resulting entity set. The options $top and $skip are used for paging in your UI. If you would like to use these options as well, register your POWL service for cache use.

As of user interface add-on 1.0 SPS 04 the POWL enabling service has been enhanced to enable selection criteria.

The POWL selection criteria and result lists are interpreted by the Web Dynpro generic POWL UI (Web Dynpro application POWL) as follows: The POWL feeder method IF_POWL_FEEDER~GET_SEL_CRITERIA retrieves the selection criteria for a POWL query. Feeder method IF_POWL_FEDER~GET_OBJECTS applies the selection criteria to the database query which returns the result.

In the past the POWL enabling service only considered for selection options fields of the result structure. With SPS 04 all selection criteria defined by feeder method IF_POWL_FEEDER~GET_SEL_CRITERIA are also considered. This is because theoretically the selection criteria might not appear as fields in the result list.

It is therefore now possible to expose any POWL application ID and its queries as an OData service.

Related Information

Cache for OData Services [page 383]

1.2.3.2.1 Architecture

The following diagram shows the architecture of the POWL enabling service:

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 381

Users operate browsers that send http requests to the SAP NetWeaver Gateway server.

The SAP NetWeaver Gateway server forwards the request to the SAP NetWeaver Gateway component in the back-end system using an RFC connection.

The SAP NetWeaver user interface services POWL framework is called. The SAP NetWeaver UI services POWL framework reads the POWL application ID and the associated queries from the SAP NetWeaver UI services POWL Customizing. Using this information, the SAP NetWeaver UI services POWL framework performs the following actions:

● It reads the POWL framework to construct the OData model.● It reads the POWL framework to retrieve the data.

382 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.3.2.2 Exposing a POWL as an OData Service

This topic provides an overview of the steps required to expose a POWL as an OData service.

Step Activity Description

1 Register a POWL application ID for OData consumption

In SAP Reference IMG, choose SAP NetWeaver UI TechnologiesSAP NetWeaver User Interface Services Register POWL for OData

consumption (transaction /UI2/POWL).

NoteWhen entering a transaction code into the command field in SAPGUI, do not forget to precede the transaction code by /n or a similar command. For more information, see Getting Started Using SAP Software SAPGUI for Windows Navigating the SAP Window Performing a Typical Task Transaction Codes .

For more details, see the IMG activity documentation.

For information about the authorizations required to perform this activity, see the section Authoziations in the User Interface Add-On for SAP NetWeaver Security Guide.

2 Register an OData service in the back-end system

In SAP Reference IMG, choose SAP NetWeaver Gateway Service Enablement Service Development for Backend OData ChannelMaintain Services (transaction /iwbep/reg_service).

Use the following settings:

● Data Provider Class: /UI2/CL_POWL_APPLID_DATA● Technical Model Name: Enter the technical name that you

specified in step 1.● Model Provider Class: /UI2/CL_POWL_MODEL_CUST

3 Activate the OData service on the SAP NetWeaver Gateway server

In SAP Reference IMG on the SAP NetWeaver Gateway server, choose SAP NetWeaver Gateway OData ChannelAdministration General Settings Activate and Maintain Services(transaction /iwfnd/maint_service).

1.2.4 Cache for OData Services

An OData service call can produce entity sets that are so large that it can take many seconds or even minutes to return them to the consumer. What is more, moving to the next page causes the data to be read from the database again before positioning to that page. Users do not want to wait a long time for the system to respond. In such a case it makes sense to use a cache mechanism for storing entity sets. We call this the cache for OData services.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 383

The main benefits of the cache for OData services are as follows:

● Performance improvements resulting from storing complete entity sets in a clustered database● Support for OData system query options $filter, $orderby, $skip and $top. These are used for filtering

the data (selection criteria), sorting the result list and paging in the UI ($skip and $top). The cache for OData services improves applications by adding the capability of selecting and sorting the data as well as paging through the result in the UI.

OData services can be registered for using the cache in Customizing by using transaction /N/UI2/CACHE.

Create a new entry for your service and fill in the following fields:

● Service name: The the name of your service which you have registered with transaction /IWBEP/REG_SERVICE

● Data provider class: It must always be /UI2/CL_GW_DP_CACHE● Filtering: Select if the application called supports filtering. This has the effect that the filter criteria are stored

in the cache.● Sorting: Select if the application called supports sorting. This has the effect that the sort criteria are stored in

the cache.● Paging: Select if the application called supports paging. This has the effect that the page criteria are stored in

the cache.● Cache active: Select to activate the cache for your service.

If you do no set filtering, the cache reads all data from the database and stores them in the cache. Filtering is then taken over by the cache.

If you set filtering, the cache selects the data from the database and stores them in the cache. Different selection criteria therefore result in different cache records. The same logic applies to sorting and paging.

Another feature is the retention of data in the cache. We differentiate between two cases:

● Client-side cache deletion:The developer decides when to delete the cache by using the OData operation refreshCache.

● Server-side cache deletion:An event in the back end initiates a cache deletion, for example, a change of a Web Dynpro CHIP configuration. It triggers the deletion of the CHIP catalog and it deletes the cache where the CHIPs are stored.

1.2.4.1 Architecture

The figure below illustrates the deployment of the cache for the POWL enabling service and is followed by an explanation:

384 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

The user operates in front of the browser and sends his http request to the Gateway server.

The Gateway server in turn forwards the request using RFC to the Gateway OData Channel which resides in the back end.

The cache for OData services is called. It builds the cache key (hash code) using the information supplied by the Gateway (such as selection criteria and navigation path). It then looks up the cache for that key. If the data is found it is returned to the Gateway.

If no data is found in the cache, the call is delegated to the data provider of the service (here the POWL–OData enabling service) which has been specified in Customizing.

If the data is found it is returned to the Gateway. At the same time it is added to the cache.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 385

1.2.4.2 Registering an OData Service for Caching

This section describes the steps you perform to register an OData service for caching.

As an example we use the POWL enabling service. Note that here you have to skip step 2 as this has already been implemented in advance in the POWL enabling framework.

1. Use transaction /UI2/CACHE to register your service and your entity data provider for cache use.Specify the following parameters:

○ Service Name: The name of the service○ Data Provider Class: The service's data provider class

In our case it is /UI2/CL_POWL_APPLID_DATA.○ Filtering: Select the checkbox○ Cache active: Select the checkbox. To deactivate the cache, deselect the checkbox.

2. Enhance your model provider (here class /UI2/CL_POWL_MODEL_CUST) so that it includes the action 'RefreshCache' defined in the cache model provider /UI2/CL_GW_MP_CACHE. Change method DEFINE as shown below:

* include action 'RefreshCache' defined in external model /ui2/gw_cache_model.* mpc is /ui2/cl_gw_mp_cache.me->model->extend_model(iv_model_name = /ui2/cl_gw_mp_cache=>gc_cache_model_name ).

3. Always specify as data provider class /UI2/CL_GW_DP_CACHE when registering your service in the back end. As model provider specify the one pertinent to your service. In the POWL case it is the generic model provider /UI2/CL_POWL_MODEL_CUST. This is done with transaction /IWBEP/REG_SERVICE in the OData Channel (back end).

4. Activate the service on the Gateway server. Use transaction /IWFND/MAINT_SERVICE to activate the service on the Gateway server. In our example the Gateway server is G3J_300.

1.2.5 ABAP APIs

1.2.5.1 Launchpad Service API

SAP NetWeaver user interface services provide an ABAP API that you can use to retrieve the content of launchpads that have been defined in transaction LPD_CUST. This is the API that is used by the OData-based launchpad service.

The launchpad service API is defined in class /UI2/CL_LAUNCHPAD_DA. In this class, the interface UI2/IF_LAUNCHPAD_ACCESS is implemented.

386 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Method Overview

Table 8: UI2/IF_LAUNCHPAD_ACCESS Methods

Method Description

/UI2/IF_LAUNCHPAD_ACCESS~GET_LAUNCHPAD_LIST

Returns a list of folders and applications for a launchpad.

/UI2/IF_LAUNCHPAD_ACCESS~GET_URL Returns a single URL with optional parameters.

/UI2/IF_LAUNCHPAD_ACCESS~GET_URLS Returns multiple URLs with optional parameters.

/UI2/IF_LAUNCHPAD_ACCESS~GET_URLS_MP Returns multiple URLs with multiple optional parameters.

/UI2/IF_LAUNCHPAD_ACCESS~GET_LAUNCHPAD_CONTENT

Returns a list of launchpad entries below a given folder, or a single entry.

1.2.5.1.1 Method GET_LAUNCHPAD_LIST

Method /UI2/IF_LAUNCHPAD_ACCESS~GET_LAUNCHPAD_LIST

Returns a list of folders and applications for a launchpad.

Table 9: ParametersParameter Type ABAP Type Description

IV_ROLE Importing APB_LPD_ROLE Name of a launchpad role as defined in transaction LPD_CUST

Together with the instance, it uniquely identifies a launchpad.

IV_INSTANCE Importing APB_LPD_INSTANCE Name of a launchpad instance as defined in transaction LPD_CUST

Together with the role, it uniquely identifies a launchpad.

IT_FILTER_SELECT_OPTIONS

Importing /IWBEP/T_MGW_SELECT_OPTION

Select options

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 387

Parameter Type ABAP Type Description

The value is passed to the feeder class.

For more information, see Filtering URLs Using a Feeder Class [page 395].

ET_CONTENT Exporting /UI2/IF_LAUNCHPAD_ACCESS=>T_LP_CONTENT

Table of launchpad entries

The description of the launchpad entries is returned in the user's logon language.

Among others, it contains the field additional_info for the additional information content of application entries of a launchpad.

ExampleThe following example requires that a launchpad with role name “UT” and instance name “UT” is defined in transaction LPD_CUST.

data: lp type ref to /ui2/cl_launchpad_da.data: lt_cont TYPE /UI2/IF_LAUNCHPAD_ACCESS=>T_LP_CONTENT.data: ls_cont type /UI2/IF_LAUNCHPAD_ACCESS=>s_LP_CONTENT.

call method /ui2/cl_launchpad_da=>get_launchpad_reference receiving ro_launchpad_da = lp.

call method lp->/ui2/if_launchpad_access~get_launchpad_list EXPORTING iv_role = 'UT' iv_instance = 'UT' IMPORTING et_content = lt_cont.

loop at lt_cont into ls_cont. write: /(10) ls_cont-role, at 20 ls_cont-instance, at 25 ls_cont-application_type , at 30 ls_cont-alias, at 40 ls_cont-text, at 60 ls_cont-additional_info , /.endloop.

388 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.5.1.2 Method GET_URL

Method /UI2/IF_LAUNCHPAD_ACCESS~GET_URL

Returns a single URL with optional parameters. This can be an absolute URL or an LPD URL.

Table 10: ParametersParameter Type ABAP Type Description

IV_ROLE Importing APB_LPD_ROLE Name of a launchpad role as defined in transaction LPD_CUST

Together with the instance, it uniquely identifies a launchpad.

IV_INSTANCE Importing APB_LPD_INSTANCE Name of a launchpad instance as defined in transaction LPD_CUST

Together with the role, it uniquely identifies a launchpad.

IV_KEY Importing APB_LPD_GUID Key of a launchpad entry (application or folder)

IT_PARAMETERS Importing T_PARAMETERS Table with name-value pairs containing additional business parameters to be added to the application URL

All IT_PARAMETERS are used for the single URL.

IT_FILTER_SELECT_OPTIONS

Importing /IWBEP/T_MGW_SELECT_OPTION

Select options

The value is passed to the feeder class.

For more information, see Filtering URLs Using a Feeder Class [page 395].

EV_URL Exporting STRING Constructed absolute URL

EV_LPD_URL Exporting STRING Constructed LPD URL

CT_POST_BODY Changing T_PARAMETERS Table with name-value pairs containing parameters to be used during navigation

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 389

ExampleThe following example requires that there is a launchpad which includes an application with the alias SAP and the URL http://www.sap.com/search/index.epx .

DATA lp_da TYPE REF TO /ui2/cl_launchpad_da.DATA lt_cont TYPE /ui2/if_launchpad_access=>t_lp_content. DATA ls_cont TYPE /ui2/if_launchpad_access=>s_lp_content.

CALL METHOD /ui2/cl_launchpad_da=>get_launchpad_reference RECEIVING ro_launchpad_da = lp_da.

CALL METHOD lp_da->/ui2/if_launchpad_access~get_launchpad_list IMPORTING et_content = lt_cont.

DELETE lt_cont WHERE alias <> 'SAP'.

READ TABLE lt_cont INTO ls_cont INDEX 1.IF ls_cont IS NOT INITIAL.

DATA: lt_params TYPE /ui2/if_launchpad_access=>t_parameters, ls_param TYPE ihttpnvp, lt_p TYPE /ui2/if_launchpad_access=>t_parameters, lv_url TYPE string.

ls_param-name = 'Query'. ls_param-value = 'Walldorf+research'. INSERT ls_param INTO TABLE lt_params.

DATA lv_role TYPE apb_lpd_role. DATA lv_instance TYPE apb_lpd_instance. lv_role = ls_cont-role. lv_instance = ls_cont-instance.

CALL METHOD lp_da->/ui2/if_launchpad_access~get_url EXPORTING iv_role = lv_role iv_instance = lv_instance iv_content_key = ls_cont-content_key it_parameters = lt_params IMPORTING ev_url = lv_url CHANGING ct_post_body = lt_p.

WRITE: lv_url,/.ENDIF.

Result:

http://www.sap.com/search/index.epx?q1=Walldorf+research

390 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.5.1.3 Method GET_URLS

Method /UI2/IF_LAUNCHPAD_ACCESS~GET_URLS

Returns multiple URLs with optional parameters. You can filter the list of application URLs to be returned.

To restrict the list of URLs, you can provide a list of application aliases as well as a list of application keys. If one of these tables is filled, the API only returns the URLs of matching launchpad applications. You can use both tables independently of each other.

Based on the selection conditions of role, instance, and alias table or key table, a list of application URLs is retrieved from the launchpad. In the table IT_PARAMETERS, you can specify additional business parameters to be added to the application URLs.

Table 11: ParametersParameter Type ABAP Type Description

IV_ROLE Importing APB_LPD_ROLE Name of a launchpad role as defined in transaction LPD_CUST

Together with the instance, it uniquely identifies a launchpad.

IV_INSTANCE Importing APB_LPD_INSTANCE Name of a launchpad instance as defined in transaction LPD_CUST.

Together with the role, it uniquely identifies a launchpad.

IT_ALIAS Importing

Optional

T_LP_ALIAS Table of application aliases

IT_KEYS Importing

Optional

T_LP_CONTENT_KEY Table of keys of aunchpad entries (applications or folders)

IT_PARAMETERS Importing

Optional

T_PARAMETERS Table with name-value pairs containing additional business parameters to be added to the application URLs

Each individual parameter that you specify in IT_PARAMETERS is added to each application URL that has been retrieved from the launchpad. If the

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 391

Parameter Type ABAP Type Description

selection for a role, instance and alias table or key table returns n applications, and the table IT_PARAMETERS contains m entries, the table ET_URL will contain m*n URLs.

NoteMake sure that the IT_PARAMETERS are valid in the context of the selected launchpad applications. In case a URL cannot be resolved, an error is returned as text in ET_URL.

IT_FILTER_SELECT_OPTIONS

Importing /IWBEP/T_MGW_SELECT_OPTION

Select options

The value is passed to the feeder class.

For more information, see Filtering URLs Using a Feeder Class [page 395].

ET_URL Exporting T_LP_CONTENT_URL Table of absolute URLs

This table has the following fields:

● alias (type string)● key (type

apb_lpd_guid)● is_param (type

ihttpnvp)● url (tpye string)● post_body (type

t_parameters)

ET_LPD_URL Exporting T_LP_CONTENT_URL Table of LPD URLs

392 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.5.1.4 Method GET_URLS_MP

Method /UI2/IF_LAUNCHPAD_ACCESS~GET_URLS_MP

Returns multiple URLs with multiple optional parameters. You can filter the list of application URLs to be returned.

To restrict the list of URLs, you can provide a list of application aliases as well as a list of application keys. If one of these tables is filled, the API only returns the URLs of matching launchpad applications. You can use both tables independently of each other.

Based on the selection conditions of role, instance, and alias table or key table, a list of application URLs is retrieved from the launchpad. In the table IT_PARAMETERS, you can specify additional business parameters to be added to the application URLs.

Table 12: ParametersParameter Type ABAP Type Description

IV_ROLE Importing APB_LPD_ROLE Name of a launchpad role as defined in transaction LPD_CUST

Together with the instance, it uniquely identifies a launchpad.

IV_INSTANCE Importing APB_LPD_INSTANCE Name of a launchpad instance as defined in transaction LPD_CUST.

Together with the role, it uniquely identifies a launchpad.

IT_ALIAS Importing

Optional

T_LP_ALIAS Table of application aliases

IT_KEYS Importing

Optional

T_LP_CONTENT_KEY Table of keys of launchpad entries (applications or folders)

IT_PARAMETERS Importing

Optional

T_PARAMETERS Table with name-value pairs containing additional business parameters to be added to the application URLs

All parameters that you specify in IT_PARAMETERS are added to each application URL that has been retrieved from the

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 393

Parameter Type ABAP Type Description

launchpad. If the selection for a role, instance and alias table or key table returns n applications, the table ET_URL will contain n URLs.

NoteMake sure that the IT_PARAMETERS are valid in the context of the selected launchpad applications. In case a URL cannot be resolved, an error is returned as text in ET_URL.

IT_FILTER_SELECT_OPTIONS

Importing /IWBEP/T_MGW_SELECT_OPTION

Select options

The value is passed to the feeder class.

ET_URL Exporting T_LP_CONTENT_URL Table of application URLs

This table has the following fields:

● alias (type string)● key (type

apb_lpd_guid)● url (type string)● post_body (type

t_parameters)

ET_LPD_URL Exporting T_LP_CONTENT_URL Table of LPD URLs

1.2.5.1.5 Method GET_LAUNCHPAD_CONTENT

Method /UI2/IF_LAUNCHPAD_ACCESS~GET_LAUNCHPAD_CONTENT

Returns a list of launchpad entries below a given folder, or a single entry. The list can contain folders, applications, or both.

This method is used in the OData-based launchpad service provided by SAP NetWeaver user interface services.

394 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

Table 13: ParametersParameter Type ABAP Type Description

IV_PARENT_ID Importing STRING ID of a launchpad entry

Specify this parameter to retrieve all children of a folder.

IV_ID Importing STRING ID of a launchpad entry

Specify this parameter to retrieve a specific launchpad entry.

IV_TYPE Importing STRING If set, restricts the type of launchpad entries to be retrieved:

● 'FL': folders only● 'URL': application

URLs only

IT_FILTER_SELECT_OPTIONS

Importing /IWBEP/T_MGW_SELECT_OPTION

Select options

The value is passed to the feeder class of the launchpad. In order to use the filter, the interface /ui2/if_launchpad_feeder must be implemented in the feeder class.

ET_URL Exporting /UI2/IF_LAUNCHPAD_ACCESS=>T_LPAD_TREE

List of launchpad entries

1.2.5.1.6 Filtering URLs Using a Feeder Class

The methods GET_LAUNCHPAD_LIST, GET_URL and GET_URLS provide the parameter IT_FILTER_SELECT_OPTIONS. This parameter allows you to pass parameters to your own feeder class in order to filter the results that will be returned by the API. If you want to use this functionality, you have to perform the following steps:

1. Write a feeder class that implements the interface /UI2/IF_LAUNCHPAD_FEEDER.

If this interface is implemented, the methods mentioned above can pass the table IT_FILTER_SELECT_OPTIONS to the feeder class.

2. In the Customizing table view /UI2/LPD_FEEDERV, assign the feeder class to the launchpads (combinations of role and instance) on which you want the filter to apply.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 395

1.2.6 Developing Applications for the Launchpad

This section provides information for developers about developing applications for the launchpad.

Table 14:Description Reference

Information about which services are available http://help.sap.com/nw-uiaddon JavaScript Docs for SAP NetWeaver User Interface Services

JavaScript Services [page 332]

Information about which APIs you can use ABAP APIs [page 386]

Information about the sandbox environment that you can use for local development and testing.

Local Sandbox Environment for the Launchpad [page 396]

1.2.6.1 Local Sandbox Environment for the Launchpad

The sandbox environment is a simplified Fiori launchpad environment that you can use for local development and testing.

This allows you to ensure that the application can be embedded properly into the Fiori launchpad. The sandbox shell implementation uses local configuration files instead of ABAP or HANA back-end services.

The Fiori sandbox is provided as part of SAPUI5 SDK. The configuration of Fiori applications and their navigation targets is stored locally. The data entered here is similar to what is configured in the ABAP system.

With the local sandbox environment you can:

● Ensure your SAPUI5 Fiori application can run embedded in the launchpad, that is, it must not define any script, stylesheet, or other dependencies in its HTML file, but only in its “main SAPUI5 component”. This main SAPUI5 component is defined in the sandbox configuration.

● Use unified shell services either implicitly (the environment does the job for you without any coding) or through API calls without back-end configuration.

● Test the unified shell services to ensure they work properly for your Fiori application as far as possible in a pure local environment (apart from application-specific OData services called).

Location of the Sandbox

After you created a UI5 application project, you can find the sandbox as part of the ushell-lib.

Related Information

bd8ae3d327ab4541bcce8e7353c046fc.xml

396 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

1.2.6.1.1 Run the Sandbox Demo Application

RecommendationWe recommend that you use only the browsers supported for SAPUI5 to run your applications.

After you have created a new SAPUI5 application project, you should be able to run the Fiori sandbox shell on your local test server, because it is displayed as a resource of the project. The relative path of the sandbox shell is test-resources/sap/ushell/shells/sandbox/fioriSandbox.html. For example, if your project is called MyFioriApplication, the URL on a local tomcat server is usually http://localhost:8080/MyFioriApplication/test-resources/sap/ushell/shells/sandbox/fioriSandbox.html.

The sandbox contains some demo applications that show how navigation within a Fiori launchpad shell runtime should be realized. The first application (which is the default application) just contains links for launching all configured applications. The other sample applications demonstrate different approaches for inner-app and app-to-app navigation inside the Fiori launchpad. All demo applications use resource-based navigation. You can recognize this easily in the browser's location bar.

CautionThe demo applications provided right now as part of the sandbox are not intended as complete reference applications for Fiori, but just for demonstrating the navigation concepts in the Fiori launchpad.

You can find the sources of the demo applications as part of the ushell-lib library under Java ResourcesLibraries SAP UI5 Core Libraries com.sap.ushell.ushell-lib-<Version>.jar , path META-INF/test-resources/sap/ushell/demoapps. You can open all library files in a read-only editor.

Related Information

SAPUI5 Developer Guide [page 3]The UI development toolkit for HTML5 (SAPUI5) is a user interface technology that is used to build and adapt client applications.

1.2.6.1.2 Run Your Own Applications in the Sandbox

Configure the SAPUI5 Component to Be Embedded

The Fiori sandbox runs your local Fiori apps inside the Fiori launchpad. You have to create a root component for the application. The demo apps serve as reference (see for instance /test-resources/sap/ushell/demoapp/FioriSandboxDefaultApp/Component.js).

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 397

The Fiori sandbox comes with a default configuration file for the demo apps, which is stored under test-resources/sap/ushell/shells/sandbox/fioriSandboxConfig.js (deployed in jar file). The sandbox tries to load an additional configuration file from path /appconfig/fioriSandboxConfig.json and merges the configuration (entries in above files overwrite the ones in lower files).

Therefore, you have to set up a local Java Web server and deploy the configuration as an additional Web module.

Create a local configuration file as follows:

1. Create a new Web project using File New Dynamic Web Project and use the project name appconfig.2. Create a file fioriSandboxConfig.json under the WebContent folder of the project.3. Edit the file.4. Deploy appconfig on the local test server:

a. Open the Servers view.b. Double-click the root node.c. Go to the Modules tab.d. Choose Add Web Module.e. Choose the appconfig project.

It is important that the path is called /appconfig.f. Restart the test server.

These configurations modify the global variable sap.ushell.fiorisandbox.configuration.applications, which as of now maps a URL hash (which is the empty one for the default application) to an application object.

What to Configure

The local configuration is stored in the JSON format. You can configure a list of applications. The applications have a key that is used for launching. This key is composed of the syntax <SemanticObject>-<Action>. For each application, specify the following attributes:

The attribute additionalInformation in this object refers to the name of the root component of your SAPUI5 Fiori application (without ".Component"). The URL attribute has to be set to the root path of your application (the folder where you would have your Component.js files), the application type for SAPUI5 applications is always URL.

ExampleYou have created a SAPUI5 application that is deployed on your local test server under path '/MyFioriApplication'. You have created a root component called “MyFioriApplication”. Then the configuration file must be as follows:

fioriSandboxConfig.json

{"applications" : { "MyFioriObject-display" : { "additionalInformation" : "SAPUI5.Component=MyFioriApplication", "applicationType" : "URL", "url" : "/MyFioriApplication", "description" : "MyFioriApplication" }

398 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

}}

CautionThe key “MyFioriObject-display” must be constructed from two identifiers with a dash, not “MyFioriObject display” or “MyFioriObjectdisplay”.

Related Information

Test Your SAPUI5 Application on a Java Web Server [page 279]

1.2.6.1.3 Embedding SAPUI5 Applications into the Fiori Launchpad Application Container

The container is able to embed a SAPUI5 component. It is embedded directly into the page, no IFRAME is used.

SAPUI5 components are described with applicationType "URL", a base URL and the component name in additionalInformation. The format is SAPUI5.Component=componentName. The application container will register a module path for the URL with the component's name.

Query parameters from the URL can be retrieved on the component instance using method getComponentData(). They are set in property "startParameters" and always passed as arrays.

ExampleLet URL be "http://anyhost:1234/path/to/app" and additionalInformation be "SAPUI5.Component=sap.foo.bar". Then the container registers the path "http://anyhost:1234/path/to/app/" for the namespace "sap.foo.bar", and then loads the component "sap.foo.bar".

ExampleLet URL be "http://anyhost:1234/?foo=bar&foo=baz&bar=baz". Then the componentData object will be:

{startupParameters: { foo: ["bar", "baz"], bar: ["baz"] }}

CautionThe container control embeds a component only. This can only work if this component is fully encapsulated and properly declares all dependencies in its metadata object. If you want your component to be able to be embedded into a shell using this container, you have to prepare it accordingly:

● The container control can only embed components that originate on the same server as the shell due to the browser's same origin policy. Consider using an SAP Web Dispatcher in this case.

Developer Guide for User Interface Add-OnDeveloper Guide © 2013 SAP AG or an SAP affiliate company. All rights reserved. 399

● If your component relies on some additional Javascript, declare the dependencies to libraries or other components in the metadata object.

● Do not use jQuery.sap.registerModulePath() with a relative URL. The base for this relative URL is the Web page. And this page is the shell when embedding the component via the container, not the page you used when developing the component.

● If your component needs additional styles, declare them using the includes property of the component metadata object.

● Consider calling jQuery.sap.getModulePath(<componentName>) to determine the root path of your component.

● If any of these requirements is not met, it is still possible to embed this view with its own page using applicationType="URL", no additionalInformation, and the URL of the Web page in url. Then of course it is embedded using an IFRAME. This has many limitations, in particular resource-based navigation using hash changes will not be supported.

400 © 2013 SAP AG or an SAP affiliate company. All rights reserved.Developer Guide for User Interface Add-On

Developer Guide

www.sap.com/contactsap

© 2013 SAP AG or an SAP affiliate company. All rights reserved.No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice.Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. National product specifications may vary.These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries.Please see http://www.sap.com/corporate-en/legal/copyright/index.epx for additional trademark information and notices.