Installing the SAPUI5 SDK Samples

My previous post “Getting started with SAPUI5” provides the steps required to get the SAPUI5 SDK documentation installed and ready for use on your local machine using Visual Studio.

The SAPUI5 SDK documentation also includes lots of live code samples. To get them up and running requires some additional steps.

Installing the SAPUI5 SDK Samples

  • unzip HTML5Beta_complete/demokit/WEB-INF/lib/demokit-uilib-1.2.0
  • inside the unzipped demokit-uilib-1.2.0, copy the META-INF/resources/sap/ui/demokit folder into the previously created /resources/sap/ui folder

Your SDK folder should now look like this:


If you open the SAPUI5 documentation and navigate to the Controls > Button page, you should see:


Via the ‘Show Source’ link you can see and even change/re-run the source code, which allows you to easily experiment with the configuration settings:


The SDK samples provide a good impression of the look & feel of the SAPUI5 controls. The screenshots below show some of the available SAPUI5 Controls (using the “gold reflection” theme).

















Menu and MenuButton











More information

For more information, visit the SAPUI5 SDK developer center on SDN.

Thanks for reading!

Getting started with SAPUI5

There are some great HTML5 UI frameworks available in the marketplace: Sencha Touch, KendoUI and Twitter Bootstrap to name just a few. And now SAP has unveiled the Beta version of SAPUI5, officially known as “UI development toolkit for HTML5”.

As a follow up on my post on Building a SAP mobile app with Sencha Touch 2, I was keen on having a hands-on with SAPUI5. These helpful posts helped me to get started.

In this post we’ll set up the Beta version of SAPUI5 for use in Visual Studio and create a demo SAPUI5 app that fetches SAP ERP Sales Orders from SAP Gateway and combines them with issues tracked in a SharePoint list.

Installing the SAPUI5 SDK on Visual Studio 2010

  1. Visit the homepage for SAPUI5 on SDN and download the trial version (SAPUI5 beta)
  2. Unzip the downloaded file
  3. Open the folder with extracted content. Unzip ‘’. You will need the ‘resources’ folder for development
  4. Rename demokit.war to and unzip. This archive contains the documentation which you can install locally.
  5. In Visual Studio, create a solution and within the solution ‘Add a new web site’
  6. Copy the contents of the demokit into the web site
  7. Copy the resource folder of to the web site
  8. Rename index.html to default.html (the VS dev server opens default.html instead of index.html when browsing a directory).
  9. Your file/folder structure should now look like this:image
  10. Now select the web site and ‘View in Browser’

You now have access to the documentation of SAPUI5:


A first test

Now we have the documentation up and running, we create our first test to see if we have all the required files.

To run this test, setup a new project or website in VS. Copy the ‘resources’ folder from sapui5-static into the site and create the following test.html file:

<!DOCTYPE html>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>SAPUI5 test</title>
        <script id="sap-ui-bootstrap"
            $(function () {
                // show an SAPUI5 alert box
                sap.ui.commons.MessageBox.alert("SAPUI5 ready for action.");

The test.html file instructs the browser to load the sap-ui-core.js file which contains jQuery and also a dynamic loader which will load further required js and css files. To show that everything loads correctly, we simply create an alert box (one of the SAPUI5 controls) when the DOM is ready.

View the test.html file in the browser and you see:


OK, we’re all set to do something a little more exciting!

Building a demo app

Consider the following business scenario: a company is managing Sales Orders in SAP ERP. To improve order fulfillment, they use a issue tracking workflow system in SharePoint. Their requirement is to see the info from SAP and SharePoint in a single screen. Let’s build that with SAPUI5!

We will connect to the online SAP Gateway demo system to fetch Sales Orders from SAP ERP. Using the demo SAP Gateway system, you can try out SAPUI5 without having to install/configure any server side components.

Our issue tracking list is part of a SharePoint Online site (SharePoint Online is part of Microsoft’s Office365 offering). Each Issue contains a field Sales Order ID which we will use to filter. Here’s how the Issues look inside the SharePoint site:


Both SAP Gateway and SharePoint are OData providers, so we will use SAPUI5’s OData model to connect to the backend systems and parse the responses. Our application page will present three tables:

  • Sales Orders: the master table showing the available Sales Orders
  • Line items: a details table showing the line items belonging to the selected Sales Order
  • Issues: a details table showing the issues tracked in SharePoint related to the selected Sales Order.

This structure is already pre-defined in the body of the index.html file:

<!DOCTYPE html>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>SAPUI5 demo</title>
        <script id="sap-ui-bootstrap"
           data-sap-ui-libs="sap.ui.commons, sap.ui.table"></script>
        <script src="app/app.js"></script>
    <body class="sapUiBody">
         <img src="images/sap_logo.png" >
         <div id="salesorders"></div>
         <div id="lineitems"></div>
         <img src="images/o365_logo.jpg" style="margin:30px 0 10px 0" />
         <div id="issues"></div>

The JavaScript of our application is contained in app/app.js.

// Let's define some shortcuts to increase
// readability of the code
var ODataModel = sap.ui.model.odata.ODataModel,
    TextField = sap.ui.commons.TextField,
    TextView = sap.ui.commons.TextView,
    Label = sap.ui.commons.Label,
    DataTable = sap.ui.table.DataTable,
    Column = sap.ui.table.Column,
    SelectionMode = sap.ui.table.SelectionMode;
// Specify the SAP Gateway SalesOrder service as an OData model
var salesOrderService =
    // The SalesOrder service requires authentication
    // get the username/password from the SDN page.
    username = "[username]",
    password = "[password]",
    // SAP Gateway only supports XML, so don't use JSON
    asJson = false,
    salesOrderModel = new ODataModel(salesOrderService, asJson, username, password)
    salesOrderCollection = "SalesOrderCollection";
// specify the SharePoint site containing the Sales Order Issues as an OData model
// we will assume there a SharePoint site called 'demo'
// which has an issues list called 'SalesOrderIssues'
var issueService =
    issueCollection = "SalesOrderIssues"  // name of SP List
    issueModel = new ODataModel(issueService);
// Create a master table with sales orders
var salesOrders = new DataTable({
    title: "Sales Orders",
    width: "100%",
    visibleRowCount: 5,
    selectionMode: SelectionMode.Single,
    editable: false
// define the relevant column properties
var salesOrderColumns = [
    { header: "Sales Order ID", value: "{SalesOrderID}", width: '100px' },
    { header: "Customer Name", value: "{CustomerName}", width: '50%' },
    { header: "Amount", value: "{TotalSum}", width: '50%' }
// create the columns
salesOrderColumns.forEach(function (column) {
    var label = new Label({ text: column.header }),
        template = new TextView({ text: column.value }),
        column = new Column({
            label: label,
            template: template,
            width: column.width
// connect the data table to the SalesOrder service
// An OData request for the SalesOrderCollection
// will return the sales orders.
// Each sales order should result in a table row.
// Put table in the DOM.
// placeAt will automatically defer if
// DOM is not ready yet (like in this demo).
// At this point the Sales Order master table is done
// Creating the lineItems and issues table is very similar
// Creating the line items datatable
var lineItems = new DataTable({
    title: "Line items",
    width: "100%",
    visibleRowCount: 10,
    selectionMode: SelectionMode.Single,
    editable: false
lineItemColumns = [
    { header: "Line item #", value: "{SalesOrderItem}", width: '100px' },
    { header: "Product Name", value: "{ProductName}", width: '50%' },
    { header: "Amount", value: "{NetSum}", width: '50%' }
lineItemColumns.forEach(function (column) {
    var label = new Label({ text: column.header }),
    template = new TextView({ text: column.value }),
    column = new Column({
        label: label,
        template: template,
        width: column.width
// Create the issues datatable
var issues = new DataTable({
    title: "Issues",
    width: "100%",
    visibleRowCount: 5,
    selectionMode: SelectionMode.Single,
    editable: false
issuesColumns = [
    { header: "Id", value: "{Id}", width: '30px' },
    { header: "Title", value: "{Title}", width: '40%' },
    { header: "Status", value: "{IssueStatusValue}", width: '10%' },
    { header: "Comments", value: "{Comments}", width: '50%' }
issuesColumns.forEach(function (column) {
    var label = new Label({ text: column.header }),
        template = new TextView({ text: column.value }),
        column = new Column({
            label: label,
            template: template,
            width: column.width
// The three data tables are ready!
// Now we need to define what should happen when
// the user selects a row in the sales order (master) table
salesOrders.attachRowSelect(function (event) {
    var Filter = sap.ui.model.Filter,
        FilterOperator = sap.ui.model.FilterOperator,
        selectedRowContext = event.getParameter("rowContext"),
        selectedSalesOrderID = salesOrderModel.getProperty("SalesOrderID", selectedRowContext),
        selectedSalesOrderLineItems = selectedRowContext + "/salesorderlineitems";
    // load the line items for the selected sales order
    // create a filter based on sales order ID
    var filter = new Filter("SalesOrderID", FilterOperator.EQ, 'SO:' + selectedSalesOrderID);
    // load the issues table using the filter
    issues.bindRows(issueCollection, null, [filter]);

Now, fire up your Chrome browser with the “disable-web-security” command line. This will suppress the Same Origin Policy which normally doesn’t allow you to do XHR request across domains:


Now you can view index.html in Chrome:


We have just build our first mash-up of SAP ERP and SharePoint data using SAPUI5!


SAPUI5 provides a number of themes. The theme used in this example is called ‘sap_platinum’. You can find other themes in the /resource/sap/ui/*/themes folders. Here are screenshots of the same page using the other themes (click the images to enlarge):

imageTheme: sap_goldreflection imageTheme: sap_ux
imageTheme: sap_hcb imageTheme: base

My first impressions on SAPUI5:

  • Offers a comprehensive set of UI widgets and layouts
  • Huge code base. Definitely not a micro-framework Smile.
  • Amazingly little code is required to get a demo app with OData sources described above up and running.
  • Includes jQuery (version 1.4.4. included in sap-core-ui.js)
  • Includes datajs.js(OData library by Microsoft)
  • Style and idiom is a bit verbose and seems to be influenced by Java. This may be a pro or a con, depending on where you are coming from.

Overall SAPUI5 is a very interesting entrant in the marketplace and sure to further boost the position as HTML5 as UI platform.

I hope this post is helpful in starting to explore the SAPUI5 Beta yourself.

Thanks for reading!

UPDATE (Oct 2012): SAPUI5 now includes mobile controls. See comment below from Ruben.

Building a SAP mobile app with Sencha Touch 2

In this tutorial we are going to build a mobile app which connects to SAP systems through SAP Gateway. The app is developed completely in JavaScript using the Sencha Touch 2 framework. Once development is completed we will package the application as a native iOS app using the new Sencha Packager.

In this tutorial we will cover:

  • an outline of the tools we are going to use
  • JavaScript code for basic functional app
  • running the app in a desktop browser
  • packaging and running the app in the iPhone simulator
  • running the app on your iPhone

Introducing the cast…

Sencha Touch is a leading mobile JavaScript framework. It provides an extensive set of UI components which you can use to quickly build mobile apps that can run on many mobile devices. Sencha Touch 2 (ST2) is the latest version, and currently in Beta 3. Download the latest version.

SAP NetWeaver Gateway is a SAP server add-on that allows mobile devices (and other consumers) to connect to SAP systems using OData-based REST services. The SAP Gateway front-ends SAP systems like ERP, CRM, SRM and enables controlled read/write access to business data using HTTP(S) and OData.SAP Gateway is a centerpiece of SAP’s mobile strategy and many mobile apps provided by SAP and its business partners are using SAP Gateway as well.

At this moment, SAP Gateway (version 2 SP3) only supports OData’s AtomPub XML format.

SAP graciously provides an online demo system where you can test-drive the SAP Gateway and the ERP and CRM systems. Our mobile app is going to connect to this demo system, using the demo user account provided by SAP. On SDN (SAP Developer Network) you will find more information on SAP Gateway and you will also find examples of other integration scenarios.

Same Origin Policy

Our Sencha Touch app will need to contact a remote SAP Gateway server to exchange XML data. In a web application, the browser will enforce the Same Origin Policy (SOP). This implies that the HTML file which contains the application must be served from the same domain, port and protocol as the XHR requests are sent to.

Let’s quickly explore the options:

  • JSONP is not an option: not supported by SAP Gateway. In addition limited to read-only scenarios.
  • Use a reverse proxy, which front-ends both the SAP Gateway and the webserver which serves up the application HTML/JS/CSS files. This way the HTML file and SAP Gateway appear to be on the same server. Good option, but adds a moving part to the solution.
  • Native packaging. In a native app, the SOP does not apply. Say again?  Because the HTML file is called by webkit using the file:// protocol, the SOP does not apply. This means there are no cross domain restrictions.

For our demo app we will opt for native packaging.

A closer look at the SAP data

Before we can start building the app we need to understand the content and structure of the data we will fetch from the server. Our first basic app will fetch Activity data from the SAP CRM demo system. Let’s lookup the activities in the SAP CRM system, so we know what activity data to expect:


As you can see, there are 5 open Activities for the demo user. To retrieve the activities from the SAP Gateway as an OData feed, get the following service url:<username>&sap-password=<password>

Visit the SAP Gateway Demo page to find the username and password to use.

The server will respond with XML in OData atom feed format. Each activity is contained in an “entry” element.image

The entry element contains the properties of an Activity:image

Developing the SAP mobile app

Enough talk, time to start coding! Our initial goal is to build a first, very basic mobile app which will show the user’s open Activities in SAP CRM. In Sencha Touch we need the following classes:

  • an Activity model: a class representing an Activity (on the client side!).  Defines the fields we want to use.
  • a Gateway Proxy: responsible for fetching data from the SAP Gateway server. It cleverly uses the field definitions of the Activity model to parse the response into Activity model instances which are handed over to the store.
  • an Activities store: holds a collection of activities in the browser. The store is filled by the output of the Gateway Proxy
  • an ActivityList: a UI component which renders a list of activities contained in the store

Looking at the structure of the OData xml, we can define the Activity model class. The fields configuration tells which properties we want to be extracted from the server response into our activity objects. The fetching and parsing is delegated to the proxy:

// Define the Activity model
Ext.define('App.model.Activity', {

    extend: '',

    // the proxy config requires the sap_gateway
    requires: ['App.proxy.sap_gateway'],
    config: {

        // define the fields which we want to extract from the OData response.
        fields: [
            { name: 'Description', type: 'string' },
            { name: 'ActivityLocation', type: 'string' },
            { name: 'CategoryDescription', type: 'string' },
            { name: 'PriorityDescription', type: 'string' }

        // provide a proxy configuration
        proxy: {
            // use the special sap_gateway proxy
            type: 'sap_gateway',
            url: "<usern>&sap-password=<passsword>"

As you can see, the Activity model uses a special proxy type, identified by ‘sap_gateway’. ST2 will look for classes with an alias of proxy.sap_gateway. Also note that you need to require the proxy class in the Model before you can use it.

The proxy encapsulates the communication with remote SAP Gateway server. Our proxy needs to convert the XML data response to Model instances. Because the response is in XML, we can use an XML reader to extract the data from the server response. The XML reader uses the Activity model field definitions to determine which data to extract. With that, the SAP Gateway proxy is remarkably simple:

Ext.define('App.proxy.sap_gateway', {

    // The SAP Gateway proxy extends the built-in Ajax proxy
    extend: '',

    // It requires an XML reader class to parse the response
    requires: '',

    // Set an alias, so we can use { type : 'sap_gateway' }
    alias: 'proxy.sap_gateway',

    config: {
        // Disable use of paging params (limit, page, start)
        enablePagingParams: false,

        // Disable cache busting
        noCache: false,

        // Configure a XML reader to process the server response.
        // Each activity is contained in an 'entry' element.
        reader: {
            type: 'xml',
            record: 'entry'

Please note:

  • this proxy class is re-usable in many Model/Stores combinations. SAP backend systems provide a vast amount of ‘classes’ (in OData parlance: Entity Types): Activities, Accounts, SalesOrders, Currencies, Invoices, etc.You can re-use this proxy with any of these Entity Types.
  • the proxy is read-only: to fetch data from SAP Gateway. A read-write proxy will require additional code.

With the Activity model and Gateway Proxy in place, we can define the Activities store class:

// An Activity store is just a basic Store,
// with a preconfigured Activity model.
Ext.define('', {
    extend: '',
    config: {
        model: 'App.model.Activity'

This completes the data part of the application. Now let’s turn to the UI. We need a List to show the results when the Store has loaded the data from the SAP Gateway.

Ext.define('App.view.ActivityList', {
    extend: 'Ext.List',
    requires: ['Ext.TitleBar'],
    config: {
        // make sure this view uses the full viewport
        fullscreen: true,

        // item template: for each activity in the list,
        // show the description
        itemTpl: '{Description}',

        // put a titlebar on top of the list
        items: [{
            xtype: 'titlebar',
            docked: 'top',
            title: 'SAP CRM Activities'

The most important part is the itemTpl configuration. The item template determines how to format the activities properties in a list item. We’ll keep it very simple and just output the Description field.

Next, we need to tie all the classes together in an Ext.application and tell the application what to do upon launch.

// Don't let the loader generate unique urls to prevent caching
    disableCaching: false

// Configure the application
    name: 'App',
    models: ['Activity'],
    views: ['ActivityList'],
    stores: ['Activities'],
    launch: function () {

        // Create an Activity store
        var activityStore = Ext.create('');

        // Create an ActivityList which takes its
        // data from the Activity store
        Ext.create('App.view.ActivityList', {
            store: activityStore

        // Instruct the store to load the Activities from the
        // server. After the Activities are received, the activity
        // list is updated automatically.

As you can see, the App requires the Activity model, the Activities store and the ActivityList. Upon launch, all the application does is create a store, create the view and load data into a store.

To complete our first SAP mobile app, we will need an index.html to contain the ST and app files.

<!DOCTYPE html>
        <title>SAP demo</title>
        <link rel="stylesheet" href="lib/sencha-touch.css" type="text/css">
        <script type="text/javascript" src="lib/sencha-touch-debug.js"></script>
        <script type="text/javascript" src="app/app.js"></script>

ST2 comes with various builds. I use the sencha-touch-debug.js version, which contains the core library and uses a dynamic script loader to fetch dependencies. I found this worked well in a development setting. However, I disabled cache busting. This prevents the loader from appending unique strings in the url when it fetches the source files. Otherwise you will loose your debugging breakpoints when you refresh your browser.

Running the app in the desktop browser

OK, time to run and test the app in our desktop browser! We’ll use an http server on our local machine to serve the files to our browser. I use the development server built into VS2010, but anything will do. Let’s assume your http server runs on port 35000 and your index.html file is served at http://localhost:35000/index.html .

Remember that we need to overcome the SOP restriction to be able to test the app in our desktop browser? Luckily Chrome provides a command line option which disables the SOP.  (Safari has the same switch but it only takes effect on a Mac, not in Windows).

So, start your Chrome browser with –disable-web-security command line option:

C:\path\to\chrome.exe –disable-web-security

Enter the url for the index.html:


And lo and behold, we see the Activities that are fetched from the remote SAP CRM system!


Let’s look at Network traffic in Chrome Developer tools. You can see all the traffic caused by the dynamic loader. Our call to the SAP Gateway system is indeed allowed by Chrome (try using Chrome without the disable-web-security option and it will throw an error).


Use the XHR option in the bottom toolbar to only show the requests to SAP Gateway.

Extending the app

Now we have this basic app running we can start adding functionality. Next to CRM Activities, the SAP Gateway demo systems offers access to other business data like CRM Accounts and Sales Orders. By adding models, stores, views and navigation we can create a more advanced SAP mobile app. Check out the Sencha Touch 2 guides to see what’s possible. Here are some examples of views and detail screens that you can build:



Packaging and running the app on iPhone simulator

Now our application development is completed, we are going to package it up as a native app, using the new Sencha packager which is part of ST2. We are going to create a native package for iOS. See this guide for more info.

To use the Sencha Packager you will need a Mac OS X machine with the latest XCode installed. Following the guide, you need to create separate configuration files for each type of deployment. In this tutorial we will create 2 configuration filess:

  • simulator.json: to run the app in the iPhone Simulator
  • development.json: to run the app on your own iPhone

I created the following folders structure to house the demo project. Please note that the www folder contains all the code which we developed earlier. The app folder contains a typical folder layout for a Sencha Touch app.


The content of the simulator.json file is:

  "orientations": ["portrait"]

This configuration tells the packager to build a version of the app for Simulator and place the file in the simulator folder.

We have all the files and folders in place. Let’s package and run the app. Open a Terminal window, change to your working directory and run the packager:


If all is well, your iPhone simulator will start and run the app:


This screencast shows the app in action on the iPhone simulator.

Running the app on an iPhone

Finally, we want to run our app on a real device. To run the app on a real device you need certificates and provisioning profiles, which you can request from the Apple Developers Provisioning Portal (you will need a Apple iOS developer license).

The use of certificates and profiles is,… well …, non-trivial. So if you are new to this, check out some tutorials which explain the concepts in more detail. For those of you who are already familiar with certificates and profiles, here’s a high-level reminder.

You want to… Certificate needed Provisioning profile needed
Run app in iPhone simulator none none
Run app on your own device Development certificate Development
Send app to selected group of users (e..g. beta tester) Distribution certificate Ad Hoc Distribution
Send app to the App Store Distribution certificate App Store Distribution

Now, back to the Sencha Packager!

To create a version of the app that can run on a real device, we need to set the configuration option to “Release”. The Sencha packager will by default use your distribution certificate and App Store distribution profile. For a deployment to your own device, you have to explicitly specify your developer certificate, using the certificateAlias option.

So the development.json  configuration file contains:

  "certificateAlias":"iPhone Developer: Your Name",
  "orientations": ["portrait"]

Please note: at this moment (Feb 16, 2012) this requires you to install a patch described in this forum post. This patch will be included a future update of Sencha SDK tools versions and I will update this tutorial when the patch is not required anymore.

We can now run the Sencha Packager using development.json as configuration file and build the app. This will create an app version which is code-signed with your developer certificate. As a last step, transfer the Development provisioning profile and the app file to your device. You can use this using iTunes, Organizer in xCode or (my preference) the iPhone Configuration Utility.

Now you should be able to start your app from your device. This is a screenshot from my iPhone:


Phew..! It’s been a long way but we have our SAP mobile app running on an iPhone!

Where to go from here

We gone through the steps to create a basic app and deliver a development version to our iPhone device. As next steps you can:

  • Further extend the app
  • Create a production build from your Javascript sources (concat source files, change the ST lib build)
  • Create an AdHoc distribution and distribute to up to 100 testers

For final deployment you can consider the Apple AppStore, Enterprise deployments or SAP Mobile App Store, which offers and sells mobile apps build by SAP and its partners.

I hope this post has inspired you to further explore the exciting opportunities of using Sencha Touch 2 to create custom mobile experiences for users of SAP systems.

Thanks for reading!