Building Web User Interfaces
I have been building web user interfaces with SAP technology for many years now. I have been through the challenges of middleware solutions provide by SAP and partners. Danced with the many generations of the ITS, negotiated with the various components of the Mobile Engine so they will play nice together, and bounced off the multiple personalities of Web Dynpro.
But for me I have always found server-side scripting the best way to build web user experiences. In the SAP world this is most commonly seen as the Business Server Pages (BSP) framework but server-side scripting is the same technique used with ASP, JSP, Python, PHP, Ruby, node.js, etc. In this paradigm the HTTP request from the browser client is processed on the server which returns a payload that typically contains HTML and client-side ECMAScript which is then rendered by the browser. Pretty sophisticated user experiences can be built this way but for me server-side scripting brings up images of hourglasses as the user waits for the server to process and respond to the current request.
This paradigm is now changing – albeit in somewhat subtle ways. The best description I have seen of this is the “single page web”. Very broadly this means there is a single HTTP request/response cycle that returns pretty much all the HTML and client-side script that the browser needs to provide the user experience. Then further resources are retrieved and loaded as required asynchronously – which is to say in the background without having to block the user experience. i.e. No hourglasses.
In the SAP world NetWeaver Gateway has an important role to play here. It is the framework that provides simple REST-based API services that expose backend functionality and return a data payload – typically using the OData protocol. NW Gateway provides a very clear separation between user experience and backend so that you can use any tools or technologies you like to create the front-end UI that interacts with the backend API’s.
In the past few months I have been approached by several of my long-term customers seeking to rebuild the user interfaces I created for them earlier this century. They were happy with the functionality of the applications but wanted them “renewed” so they looked better on Apple iOS devices. One example is a warehouse management application I originally built for PPC devices. The customer is replacing these devices with scanner-equipped iPods because they are significantly cheaper than the ruggedised terminals they had been using. As part of this replacement they want the screens to better match the native iOS experience.
I considered using the SAP UI5 framework as the basis for the new UX. After all it is SAP’s favoured solution for this type of scenario and the customers were keen to use it. However I went in another direction and I would like to explain why.
Back to first principles. Here is a piece of sample HTML that demonstrates some of the standard user interface elements available to the web developer – many of which I used in my original applications. There are text fields, buttons, checkboxes, radio buttons, etc.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>HTML Example</h1>
<p>Sample text and <a href="#" >links</a></p>
<ul>
<li>List Header</li>
<li>Read-only list item</li>
<li><a href="#">Linked list item</a></li>
</ul>
<fieldset>
<input type="radio" name="radio-choice-b" id="radio-choice-1-b" value="choice-1" checked="checked" />
<label for="radio-choice-1-b">Radio Button 1</label>
<input type="radio" name="radio-choice-b" id="radio-choice-2-b" value="choice-2" />
<label for="radio-choice-2-b">Radio Button 2</label>
<input type="radio" name="radio-choice-b" id="radio-choice-3-b" value="choice-3" />
<label for="radio-choice-3-b">Radio Button 3</label>
</fieldset>
<fieldset>
<input type="checkbox" name="checkbox-b" id="checkbox-b" checked="checked" />
<label for="checkbox-b">Checkbox 1</label>
<input type="checkbox" name="checkbox-b" id="checkbox-c" />
<label for="checkbox-c">Checkbox 2</label>
<input type="checkbox" name="checkbox-b" id="checkbox-d" />
<label for="checkbox-d">Checkbox 3</label>
</fieldset>
<fieldset>
<input type="radio" name="radio-view-b" id="radio-view-a-b" value="list" checked="checked"/>
<label for="radio-view-a-b">On</label>
<input type="radio" name="radio-view-b" id="radio-view-b-b" value="grid" />
<label for="radio-view-b-b">Off</label>
</fieldset>
<select name="select-choice" id="select-choice-b">
<option value="standard">Option 1</option>
<option value="rush">Option 2</option>
<option value="express">Option 3</option>
<option value="overnight">Option 4</option>
</select>
<p><input type="text" value="Text Input" /></p>
<p><input type="range" name="slider" value="50" min="0" max="100" /></p>
<button>Button</button>
</body>
</html>
When I open this page in the iPhone browser it looks like this.
My example wont all fit on an iPhone screen so I will mainly use the iPad for my screen shots
This works and it sort of looks okay – we could certainly pretty it up a bit if we wanted – but it would take quite a bit of effort to make it look anything resembling a native iOS application. Fortunately other people have already done the heavy lifting for us. There are plenty of examples freely available but I am going to use JQuery Mobile.
The JQuery Mobile framework makes use of HTML5 data- attributes for markup based initialization and configuration of widgets. For example the attribute data-role=”header” defines the page header area. You do not have to use these attributes but it certainly makes this process easier. So I take our HTML example from above, add some div tags and plenty of data- attributes then load the JQuery Mobile framework from the CDN as described on the Jquery Mobile download page/.
I also added some HTML for a Home button and a Navigation button to the header area and had them render as icons.
My HTML now looks like this – a little more verbose (and for some reason poorly formatted) but in essence the same as before. If I remove the loading of the JQuery Mobile framework the page renders exactly the same as my original example.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
</head>
<body>
<div class="preview ui-shadow swatch">
<div class="ui-header ui-bar-b" data-swatch="b" data-theme="b" data-form="ui-bar-b" data-role="header" role="banner">
<a class="ui-btn-left ui-btn ui-btn-icon-notext ui-btn-corner-all ui-shadow ui-btn-up-b" data-iconpos="notext" data-theme="b" data-role="button" data-icon="home" title=" Home ">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text"> Home </span>
<span data-form="ui-icon" class="ui-icon ui-icon-home ui-icon-shadow"></span>
</span>
</a>
<h1 class="ui-title" tabindex="0" role="heading" aria-level="1">JQueryMobile Sample</h1>
<a class="ui-btn-right ui-btn ui-btn-icon-notext ui-btn-corner-all ui-shadow ui-btn-up-b" data-iconpos="notext" data-theme="b" data-role="button" data-icon="grid" title=" Navigation ">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text"> Navigation </span>
<span data-form="ui-icon" class="ui-icon ui-icon-grid ui-icon-shadow"></span>
</span>
</a>
</div>
<div class="ui-content ui-body-b" data-theme="b" data-form="ui-body-b" data-role="content" role="main">
<p>Sample text and <a class="ui-link" data-form="ui-body-b" href="#" data-theme="b">links</a>.</p>
<ul data-role="listview" data-inset="true">
<li data-role="list-divider" data-swatch="b" data-theme="b" data-form="ui-bar-b">List Header</li>
<li data-form="ui-btn-up-b" data-swatch="b" data-theme="b">Read-only list item</li>
<li data-form="ui-btn-up-b"><a href="#">Linked list item</a></li>
</ul>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<input type="radio" name="radio-choice-b" id="radio-choice-1-b" value="choice-1" checked="checked" />
<label for="radio-choice-1-b" data-form="ui-btn-up-b">Radio Button 1</label>
<input type="radio" name="radio-choice-b" id="radio-choice-2-b" value="choice-2" />
<label for="radio-choice-2-b" data-form="ui-btn-up-b">Radio Button 2</label>
<input type="radio" name="radio-choice-b" id="radio-choice-3-b" value="choice-3" />
<label for="radio-choice-3-b" data-form="ui-btn-up-b">Radio Button 3</label>
</fieldset>
<fieldset data-role="controlgroup">
<input type="checkbox" name="checkbox-b" id="checkbox-b" checked="checked" />
<label for="checkbox-b" data-form="ui-btn-up-b">Checkbox 1</label>
<input type="checkbox" name="checkbox-b" id="checkbox-c" />
<label for="checkbox-c" data-form="ui-btn-up-b">Checkbox 2</label>
<input type="checkbox" name="checkbox-b" id="checkbox-d" />
<label for="checkbox-d" data-form="ui-btn-up-b">Checkbox 3</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<input type="radio" name="radio-view-b" id="radio-view-a-b" value="list" checked="checked"/>
<label for="radio-view-a-b" data-form="ui-btn-up-b">On</label>
<input type="radio" name="radio-view-b" id="radio-view-b-b" value="grid" />
<label for="radio-view-b-b" data-form="ui-btn-up-b">Off</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<select name="select-choice" id="select-choice-b" data-native-menu="false" data-theme="b" data-form="ui-btn-up-b">
<option value="standard">Option 1</option>
<option value="rush">Option 2</option>
<option value="express">Option 3</option>
<option value="overnight">Option 4</option>
</select>
</div>
<input type="text" value="Text Input" class="input" data-form="ui-body-b" />
<div data-role="fieldcontain">
<input type="range" name="slider" value="50" min="0" max="100" data-form="ui-body-b" data-theme="b" data-highlight="true" />
</div>
<button data-icon="star" data-theme="b" data-form="ui-btn-up-b">Button</button>
</div>
</div>
</body>
</html>
A quick refresh of the browser and it looks like this.
Quite a difference – and all I did was add a few data- attributes and load the JQuery Mobile framework. We can modify the theme extensively if we choose to. It looks pretty good on a iPhone as well.
If I build a screen using SAP UI5 that contains the same user interface elements it could look like this.
Again we can modify the theme extensively to suit our needs – I just used the default for this example. Please don’t get caught up comparing the appearance of my two very simple examples.
The real difference here is the code for building the SAP UI5 screen. Here it is.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>SAPUI5 Mobile Sample</title>
<style type="text/css">
</style>
<script src="../../../resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_mvi">
</script>
<script>
jQuery.sap.require('sap.m.Input');
var oApp = new sap.m.App("myApp", {initialPage:"page1"}),
// page
oPage1 = new sap.m.Page("page1", {
customHeader: new sap.m.Bar({
contentLeft: [new sap.m.Button({icon: sap.ui.core.IconPool.getIconURI("retail-store")})],
contentMiddle: [new sap.m.Label({text: "SAP UI5 Example"})],
contentRight: [new sap.m.Button({icon: sap.ui.core.IconPool.getIconURI("notes")})]
}),
content: [
new sap.m.HBox({
items:[
new sap.m.Text({text: "Sample text and "}),
new sap.m.Link({text : "links", press : function() {app.to("page2");}}),
]
}),
new sap.m.List({
headerText : "List Header",
items: [
new sap.m.DisplayListItem({label: "Read-only list item"}),
new sap.m.StandardListItem({title : "Linked list item",type : "Navigation"})
]
}),
new sap.m.VBox({
items:[
new sap.m.RadioButton({
text: "Radio Button 1",
selected: true,
groupName:"group1"
}),
new sap.m.RadioButton({
text: "Radio Button 2",
groupName:"group1"
}),
new sap.m.RadioButton({
text: "Radio Button 3",
groupName:"group1"
}),
]
}),
new sap.m.VBox({
items:[
new sap.m.CheckBox({selected:true, visible:true, enabled: true, text: "Checkbox 1"}),
new sap.m.CheckBox({selected:false, visible:true, enabled: true, text: "Checkbox 2"}),
new sap.m.CheckBox({selected:false, visible:true, enabled: true, text: "Checkbox 3"}),
]
}),
new sap.m.VBox({
items:[
new sap.m.Switch(),
new sap.m.Select({
title: "Select header",
items: [
new sap.ui.core.Item({key: "1", text: "Option 1"}),
new sap.ui.core.Item({key: "2", text: "Option 2"}),
new sap.ui.core.Item({key: "3", text: "Option 3"}),
new sap.ui.core.Item({key: "4", text: "Option 4"}),
],
selectedKey: "1"
}),
new sap.m.Input({placeholder : "Text Input"}),
new sap.m.Slider({value: 50}),
new sap.m.Button({
type: sap.m.ButtonType.Default,
text: "Button",
icon: sap.ui.core.IconPool.getIconURI("add-favorite")
}),
]
})
]
});
oApp.addPage(oPage1);
oApp.placeAt("body");
</script>
</head>
<body id="body" class="sapUiBody"></body>
</html>
Again it is not a lot of code if you measure it in lines – but notice that it is all JavaScript.
The JQuery Mobile example really draws on the “progressive enhancement” strategy of web design. Essentially this means it seeks to start at a lowest common denominator level of browser capability and build up from there. So we started with pretty simple HTML elements that can be rendered by most browsers and then the JQuery Mobile framework enhances these elements in a layered fashion based upon the capabilities of the specific browser. The elements will render as feature-rich as the browser makes possible.
In some respects SAP UI5 does the same thing – it is after all built upon JQuery, JQueryUI and JQuery Mobile. But it is more focused on contemporary browsers and therefore can’t be expected to work on all of them. Our JQuery Mobile example would still render the HTML elements on even the most rudimentary web browser whereas the SAP UI5 elements at least require a browser that supports JavaScript.
Getting back to my customers, who want me to renew their user interfaces, I have found it made much more sense to use frameworks like JQuery Mobile to “enhance” the existing screens than to rewrite them. The main advantages are that I can deliver the new screens in a much quicker timeframe and that these screens would continue to work on the old PPC devices using a single code line.
On the other hand if I was building a completely new set of screens from scratch, and confident that all devices would use contemporary browsers, then SAP UI5 becomes a much more attractive option.
Finally a caveat. This blog is not even close to an in-depth look at JQuery Mobile or SAP UI5. Nor is it a comparison of the capabilities of each framework. In none of my examples did I even touch upon the fairly important aspects of user event handling, page or view navigation, calling the backend, etc. Please don’t treat it as such.
Thanks
Graham Robbo
Nice blog Graham.
Interesting to me is the fact that most of the web development frameworks out there tend to use html for the view or presentation; whereas SAPUI5 is full-on JavaScript. In the newest SAPUI5 toolkit we have an experimental view type for HTML; however after playing around with this briefly its more like an XML definition than anything else with lots of un-readable deeply-nested DIV tags everywhere. The example Fiori app (provided with 1.12 seems to use these extensively.
Take a look at web frameworks/libraries such as jQueryUI; AngularJS; Bootstrap; Backbone (with a templating engine); emberJS: etc. In fact most of the todomvc.com frameworks. They all rely on using HTML for what its good at.
Yeah I take your point. For me the jury is still out on this - but I agree there is plenty of merit in using HTML for the view.
Interestingly I find the SAPUI5 MVC implementation pretty good. I like the clear separation of view and controller code into totally separate files. One thing I heard last week was that AppDesigner is seen as a tool for enforcing these sorts of coding guidelines/principles. So, for example, if you stick to the same file and coding structures then you will be able to import your application into AppDesigner, modify it there, and then export it out again.
Yep SoC into files is good - in fact absolutely necessary with js (unless its a very small app). All those other frameworks I mentioned do this as well of course (well - except for jQuery on it own I guess but still can be done)... In fact its better to go further and componentize. See this great blog by Harald Schubert on how to layout, componentize (is that even a word?) and write testable SAPUI5 applications using the great todomvc.com example.
Check out require.js as a popular module (component) loader as well.
--Jason.
I like your blog Graham!
I have a reflection about the blog:
If you build small web applications like this the choice of technology isn't that relevant. What I have noticed with SAPUI5, is that when you need to make more complex web applications, this technology does a lot of heavy lifting for the developer. This is because the technology does the integration of not only jQuery but LESS, datajs, d3.js and so on. So the developer have a technology that have much out-of-the-box and can focus on bringing business value instead of only focus on getting the integration of all the technology pieces. That I think is lacking in the debate about UI for SAP; how the business values can be meet. Another point is that when only using open source the customer don't have SAP in there back. With SAPUI5 they can get support from SAP. That I have noticed is a very important business value for the customers.
Kind regards
Morgan Apelqvist
So if I choose SAPUI5 over rolling your own jquery++ it is like if I was buying enterprise support from Redhat or Ubuntu versus getting the community edition.
Some good points here Morgan... But I'm wondering... What kind of support are you going to get from SAP? If you write your own SAPUI5 app you aint going to get any support on that of course. Only with the underlying run-time I would think.
What I meant with support is that when something is wrong with SAPUI5 technology or missing, you yell at SAP the way you prefer. If something is wrong or missing in jQuery, you yell at a forum thread, and hope someone is listening. If you are a big company, time is money and you want someone to blame if the underlying technology is messing with you.
Hi Morgan
I agree with your comment that many enterprise customers expect a solid support agreement with the vendors of software they install in their environment. I've experienced this myself. I'm guessing that SAPUI5, having a SAP "label" on it, would make these customers less nervous than an open source library. Let's just hope that OSS messages raised for SAPUI5 problems don't end up with a response like today's Dilbert comic π
http://dilbert.com/strips/comic/2013-06-13
Great blog, Graham! My own web development experience so far has been limited by some clumsy adjustments in a Blogger HTML template ("hmm, let's see what happens if I put this here..."). But, surprisingly, even I was able to understand all you were saying (it's a compliment! π ) and learned quite a bit.
I had a similar question to what Morgan already mentioned, but in more simple terms: if tomorrow those JQuery guys go out of business and take down jquery.com, what happens?
Hi Jelena and Morgan Apelqvist
thanks for your comments. You both raise valid points about support. As enterprise peeps we look for vendor support for everything shipped. But as developers we recognise the role open source has to play as well. Marrying the two together is a problem for all - not least of all SAP themselves.
We want SAP to fix any problems with the SAPUI5 library but potentially a problem might actually originate in the JQuery framework. We also want SAPUI5 to sit on top of the latest JQuery framework so we get immediate access to any new features.
And there is a strong push for SAP to open source SAPUI5. They tell us that is principle they think this would be a good idea but the "legal guys" are against it. π But as enterprise peeps we distrust the support model of open source software. A dilema!
However, one of the great things about open source JavaScript frameworks like JQuery is that we can contribute to the project ourselves and thereby help ensure its' success. And in worst case if the project dies completely we can fork our own version and correct any problems or add any enhancements we like. (Not recommending this BTW - but it is a last resort option)
Cheers
Graham Robbo
AHH the legal guys. Should we point them at what WordPress has done over 10 years? come from a fork of an obscure blogging platform to becoming the most used content platform on the web.
What about mysql or redhat?
I think opening up SAPUI5 and getting SAP to sponsor events like YOW would greatly increase the developer eyes on what SAP is doing.
Cheers,
Nigel
Good blog Graham. I am big fan of jQuery mobile because of it's simplicity. I get your point on MVC, but as you may already know, there are options to use MVC pattern with jQuery mobile as well.
Regarding the hour glass, technically it's a good practice to show the 'page loading' icon when the AJAX call is in process(in most cases we will need this) but yeah, the wait team will be far less than server side scripting. And oh, the added benefit of compressed/minified java script/CSS files is something to consider as well.
Cheers
KK
Hi KK,
I am aware you can combine jQueryMobile with Backbone.js. I have yet to try it myself. Here is a sample post, although there are others on the web blogging about it ...
http://blog.chariotsolutions.com/2011/12/introduction-to-backbonejs-with-jquery.html
Cheers
John
A great primer on getting into the brave new UI landscape from SAP. Taken with John Moy's recent blog on what skills are needed in this brave new world you are pointing us to what skills are required for the modern SAP developer.
Cheers,
Nigel
"learning Javascript used to mean you weren't a "serious software developer". today, not learning Javascript means the same thing' - @monkchips
Yep, and what is interesting is with the free course offered by SAP at open.sap.com on Introduction to Software Development on SAP HANA, it looks like it deals with server-side Javascript on HANA XS, and client-side Javascript with SAPUI5. No ABAP at all it seems.
Cheers
John
Very nice blog, thanks a lot!!
Regarding the question SAP support vs open source lib: when starting with web development and javascript years ago, my problems are often at a beginner level and i loved the web: type the problem and begin with javascript you find thousands of pages with demo code. and this is something that, as a developer with now more complicated or frameworks caused problems / needed info, ist still a point: searching for SAP UI5 google will lead to 119.000 hits, searching for jquery (108.000.000 hits) and jquery mobile (40.000.000 hits). this is for sure NOT a qualified study about support or support quality but it may indicates the support level you get when developing with open source from the community outside.
(and of course, i do NOT want to give with this a statement about the quality of the two framweworks themselve!! π
Cheers,
Ingo