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
- Visit the homepage for SAPUI5 on SDN and download the trial version (SAPUI5 beta)
- Unzip the downloaded file HTML5Beta_complete.zip
- Open the folder with extracted content. Unzip ‘sapui5-static.zip’. You will need the ‘resources’ folder for development
- Rename demokit.war to demokit.zip and unzip. This archive contains the documentation which you can install locally.
- In Visual Studio, create a solution and within the solution ‘Add a new web site’
- Copy the contents of the demokit into the web site
- Copy the resource folder of sapui5-static.zip to the web site
- Rename index.html to default.html (the VS dev server opens default.html instead of index.html when browsing a directory).
- Your file/folder structure should now look like this:
- 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> <html> <head> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>SAPUI5 test</title> <script id="sap-ui-bootstrap" src="resources/sap-ui-core.js" data-sap-ui-theme="sap_platinum" data-sap-ui-libs="sap.ui.commons"></script> <script> $(function () { // show an SAPUI5 alert box sap.ui.commons.MessageBox.alert("SAPUI5 ready for action."); }) </script> </head> <body> </body> </html>
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> <html> <head> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>SAPUI5 demo</title> <script id="sap-ui-bootstrap" src="/resources/sap-ui-core.js" data-sap-ui-theme="sap_platinum" data-sap-ui-libs="sap.ui.commons, sap.ui.table"></script> <script src="app/app.js"></script> </head> <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> </body> </html>
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 = "https://gw.esworkplace.sap.com/sap/opu/sdata/IWFND/SALESORDER", // 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 = "http://[SharePoint_server]/demo/_vti_bin/ListData.svc", 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 }); salesOrders.addColumn(column); }); // connect the data table to the SalesOrder service salesOrders.setModel(salesOrderModel); // An OData request for the SalesOrderCollection // will return the sales orders. // Each sales order should result in a table row. salesOrders.bindRows(salesOrderCollection); // Put table in the DOM. // placeAt will automatically defer if // DOM is not ready yet (like in this demo). salesOrders.placeAt("salesorders"); // 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 }); lineItems.addColumn(column); }) lineItems.setModel(salesOrderModel); lineItems.placeAt("lineitems"); // 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 }); issues.addColumn(column); }); issues.setModel(issueModel); issues.placeAt("issues"); // 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 lineItems.bindRows(selectedSalesOrderLineItems); // 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!
Themes
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):
My first impressions on SAPUI5:
- Offers a comprehensive set of UI widgets and layouts
- Huge code base. Definitely not a micro-framework
.
- 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.