Quantcast
Channel: SAPUI5 Developer Center
Viewing all 789 articles
Browse latest View live

Matt Harding’s Fiori Like Challenge - The Diversion...(Part 4)

$
0
0

Continued from Matt Harding’s Fiori Like Challenge - Low-Resolution Prototyping...(Part 3)

 

 

The Diversion

 

This blog is a more technical blog than my previous design thinking focused blogs to describe my experience in getting the development tools in place and more importantly "humming" to complete my Fiori Like Challenge. We'll be back shortly with the high resolution prototype in Part 5 but read-on if you're getting into Eclipse SAPUI5 development (or experienced already and can offer some advice).

 

Should I, Shouldn't I...

 

So we're up to building a high resolution prototype within the Fiori like SAPUI5 application and while I could easily develop this in Notepad++ and deploy either through public Dropbox folders or on IIS (my preferred HTML/JS/CSS editor/test set-up) #oldschool; I figured it is time to embrace the "everything in Eclipse" approach SAP has taken.

 

So as I like the latest for everything, I downloaded JRE 7, Eclipse (Kepler version), Tomcat 8, SAPUI5 1.16.3.1; ABAP in Eclipse, Gateway Productivity Accelerator (1.0.4), etc; and tried to put it all together.

 

Now I should point out that I have used Eclipse previously, and was quite comfortable developing within certain aspects of it so. Also, if you are thinking this blog is going to help you set everything up from scratch, it won't but it's been blogged/described about several times before on SCN and elsewhere.

 

What I will do is give you some thoughts on preferences/install steps that I would have found useful prior to starting the learning/install process.

 

Change is Good, Change is Bad...

 

So at this point, I just need to develop some dodgy web content to present as a high resolution working prototype for feedback. To date, my blog series has not been onerous (except for copying images into SCN which took more time than the low resolution design I did) and all up the design thinking effort (ignoring your time as a stakeholder) has only been a few hours.

 

This all changes with the problem of coming to grips with Eclipse and SAPUI5 (but mainly Eclipse at this point). So while I've grinded to a halt due to Eclipse SAPUI5 Web Development/Testing, I can see my productivity will increase substantially as I become more familiar with the process, and I'm sure more patterns, features for Web development in later releases will make this a no brainer, so I'm glad I'm embracing this frustrating change now!  But not really feeling it today!

 

Most Important Observation

 

Coming from developing in SAP, we've had things pretty good. Apart from the occasional very confusing, poorly integrated SAP purchased tool-sets; it typically just works from an integrated development perspective. But with SAP now promoting real not-so-Enterprise software development, and embracing powerful open-source IDE's like Eclipse, the most important aspect is, there is no basis dude there to tell you what to do and get it all working.

 

The analogy: We've had the very powerful, "it just works" but slightly limited Apple iPhones in our hands for all these years, but now we've all been given various makes and models of Google Android phones with stacks of power and options which we are allowed to customise and tailor to our heart's content meaning no one's phone is truly the same.

 

So if you're leading the charge for Fiori/SAPUI5 at your place - you probably need to get a handle on all of this, making sure you have the right versions of everything installed and configured right (there are dependencies between SDK's and SAPUI5 libraries for example); especially ensuring you understand how software change management will be done, etc; as this could be quite challenging if you have multiple developers touching aspects of the solution.

 

Other Installation Recommendations and Learnings

 

  • Originally I just used the "Run as Web App Preview" option in Eclipse for my SAPUI5 app (then copying the URL into Chrome for real testing), but it kept running into locking issues with the source files, hence why I moved to a dedicated Tomcat installation. Using Tomcat also allowed me to run the full SDK which does have some JAVA server components that don't run in the static SDK.
  • Tomcat 8 installation was straight forward, and I added the SAPUI5-SDK.war file to the Web-App and got it running quickly (available via localhost:8080/sapui5-sdk if you do this); but I found it was easier for Eclipse to work with it's own installation of Tomcat which it can also download and install for you so removed my instance and went with Tomcat 7 (since Eclipse didn't support Tomcat 8 as an install option yet).  Note - I'm sure with more time, I could have got Tomcat 8 working, but when it just works through Eclipse - don't fight the easy solution.

Tomcat Install optionJPG.JPG

  • If you use the Eclipse installation of Tomcat, to make the SAPUI5-SDK available, double click on your Tomcat server in the Servers view in eclipse, select the tab Modules, then "Add External Web Module" - After doing this, you can access the SDK in your browser from your Eclipse controlled Tomcat

SAPUI5-SDK in Tomcat.JPG

  • To get Chrome as the default browser, it is very simple, don't over complicate the thinking like I did by looking at URL parameters, etc. All you do is go to Preferences under General->Web Browser and add Chrome (see picture) - Just use "Run on Server" and you should be good to go.

Chrome Setup.JPG

  • Using Chrome developer tools (press F12), opening the Sources tab, pressing ctrl-O to look at a particular source file, is very cool and is an easy way to set up breakpoints (learnt this obvious one at SAPTechEd).
  • I couldn't get Ctrl-F11 behaving consistently for testing my app, so I created a windows short-cut to Run on Server. It's still not perfect (see below) as you have to ensure you select the project or the start file for it to behave correctly. I have no idea how to make a short-cut key to run on server and start with my start URL - Very frustrating.
  • Using Dev Tools to disable the cache temporarily can be useful.
  • SAPUI5 application and View wizards are a nice way to quickly build SAPUI5 front-ends.

 

 

My Perfect Web Development Environment and What I'm still Struggling to Find in this Set-Up

 

For Web Development, I'm very much a change something, see what happens type of guy - Even in the ABAP World, I tend to have a nervous twitch pressing Ctrl-F2 or Ctrl-F3 and press F8 frequently.

 

Part of the reasoning is to see the change as I make it, learning how things work, and just knowing I haven't made a stupid mistake.  In Web Development, part of it is I want to ensure the User Experience is consistent, and looks good (enough) but not be afraid to test out different approaches to see if I can improve aspects also.

 

Hence going from code to test near instantaneously is very important to me. To give you an idea about what the future may hold for Eclipse based development (I hope), one of the collaboration sites I came across while learning about SAPUI5 was http://jsbin.com/ - Go ahead and just start typing some HTML into the body, and automatically, you will see the preview page show exactly what is happening. Very cool stuff.

 

Obviously having intellisense, formatting options, snippets, plus all the other good stuff is awesome (and expected), but since I came from notepad++, you can probably guess the above is more important to me.

 

So as stated above, the fact that when I edit a JavaScript file (as an example) and then Run on server just displays my JavaScript file in a browser and not my app - is incredibly frustrating. Hopefully one of you know how to fix this, but provided I select the appropriate node in the Project Explorer then press my shortcut key or just leave Chrome running in the background and press refresh there, it's acceptable.

 

Now can I Finally Prototype?

 

I think I'm ready enough now - So I'm off to learn and prototype how navigation works in SAPUI5 for Fiori apps and play around with the various icons, controls, etc; to make the app nice to use (For reference, some of the icons are very and I mean very specific and hilarious coming from an Enterprise context - Anyone for an Endoscopy or Soccer). My code will most likely be awful, but the good thing is, I won't care if my stakeholders make me change it all because of it. My general rule with prototypes is you always start the final development from scratch only borrowing from your prototype especially as we usually all learn to a degree when doing a prototype and accept things we wouldn't accept for the final solution (refactoring is usually not appropriate in this scenario). Happy coding all...


Packaging sapui5 application using phoneGap for Android [ Command line Interface ]

$
0
0

    PhoneGap is an open source framework that allows you to create native apps for different platforms like ios, android, windows 8, bbos etc.

Using PhoneGap we could develop various platform apps using well known technologies like HTML5 , Javascript with a minimal platform specific skills.

There are two methods to package an SAPUI5 app using PhoneGap

 

 

    1) PhoneGap Build Service

 

 

    2) Packaging apps with CLI

 

 

PhoneGap build service is a paid service, free plan allows us to have only one private app, here i'l be concentrating on "Packaging using Command Line Interface".

 

You can download the latest version of phonegap here  .

 

Step1 : Navigate to android/bin folder in the command prompt in my case it is

 

D:\360545\phonegap-2.9.0\phonegap-2.9.0\lib\android\bin

 

 

 

 

2.JPG

 

 

 

Step 2 :

 

    Now enter command “create d:\NewAndroidApp com.phoneGap.android Approval ” and click enter. This will create an android phoneGap application.

 

3.JPG

 

 

Step 3 :

 

Open ADT, click on File -> new -> others

Expand android in wizard, and select “Android Project from existing Code”

And click on “next”.

 

 

4.JPG

 

 

 

Click on “Browse ” and navigate to the android project that you have created previously, i.e., NewAndroidApp then click ok -> check “copy projects into workspace “

click on finish.

 

5.JPG

 

 

 

Step 4:

 

  Run the app in simulator, you should see sample cordova application for android.

 

6.JPG

 

This confirms that that your phoneGap project is created.

 

 

Step 5:

 

My sapui5 folder structure is as follows  :

 

9.JPG

 

 

 

 

Let’s copy “approval” folder from WebContent and paste it in www folder of your android project

 

 

8.JPG

 

 

 

Refer these .js files in index.html file.

  1. i.e., add these two lines to index.html

 

<script type="text/javascript" src="approval/App.controller.js"></script>

 

<script type="text/javascript" src="approval/App.view.js"></script>

 

<script type="text/javascript" src="approval/App.controller.js"></script>

 

<script type="text/javascript" src="approval/App.view.js"></script>

 

 

 

 

App.view.js  :

 

 

 

sap.ui.jsview("approval.App", {

 

          getControllerName: function() {

                    return "approval.App";

          },

 

createContent : function(oController) {

 

                    this.app = new sap.m.App("App");

 

 

                    var approval = sap.ui.jsview("idApproval","approval.approval");

                    approval.app = this.app;

                    this.app.addPage(approval);

 

 

                    return this.app;

          }

});

 

and approval.view.js contains the application code.

 

 

 

Step 6:

 

Copy resources from “ sapui5-mobile-static ” and paste it under www folder.

 

 

10.JPG

 

 

 

Refer these resources in your index.html i.e.,

<script id="sap-ui-bootstrap"

type="text/javascript"

      src="/resources/sap-ui-core.js"

       data-sap-ui-theme="sap_bluecrystal"

       data-sap-ui-libs="sap.m”>  </script>

 

Step 7:

 

app.initialize() initializes the app . We have onDeviceReady() event in index.js which is fired as soon as device is ready

so we get App.view.js and place this

View at content i.e., paste following code in onDeviceReadyEvent().

 

varmyapp = sap.ui.jsview("approval.App");

   myapp.placeAt('content');

 

 

Now run the app, You should be able to see your sapui5 application in the simulator .

 

 

11.JPG

 

 

Now your app is ready .

Performance comparison of ABAP WebDynpro and SAPUI5 with Neptune Application Designer

$
0
0

EDIT: Disclaimer, I work as the CTO of Neptune Software. The comparison is viable for SAPUI5 in general tho.

 

 

It is difficult to set up a side by side comparison of different UI frameworks without having identical scenarios and backend coding. In this document we will use a common scenario which is to create a sales order. The applications used for comparison is the Lean Order for WebDynpro ABAP - lo_oif_main_app and the Neptune application nadui5_sales_order which is based on the SAPUI5 framework.

 

The first thing you will notice when comparing the two is a huge difference in perceived performance. Whereas the flow of the WDA Lean Order is constantly interrupted by the dreaded WDA spinning wheel when using the app, the SAPUI5 solution runs smoothly and gives you a native and fast user experience.

When we looked under the hood to find out why, the number of HTTP requests used by a single operation is staggeringly different. For one UI5 request the WDA solution (even when cached) used 30-40. Also a similar number of cached resources are fetched adding additional overhead.

 

This is illustrated here where the WDA enters the order page and loads 0.9 MB! For showing this screen:

 

1.png

 

If you look at the requests the sheer number is unbelievable and you quickly see where the UI layer performance overhead comes from.

 

You see calls here with up to 20 seconds response time, which is unacceptable in a modern application.

 

2.png

 

Now let’s look at the Neptune solution. The architecture is based on loading compressed native json through ajax calls into the SAPUI5 models.

 

The initial load of a single application fetches the entire user interface parts and includes the SAPUI5 library if it is not cached thus making subsequent calls extremely lean. But it is a fact that many people are not happy about the size of the SAPUI5 framework.

 

The ability to send multiple models in one ajax call reduces the number of requests drastically. The application is not directly comparable as I mentioned in the introduction but the functionality is identical. Here we see a response time of 55 ms and a mere 885 bytes received.

 

3.png

 

In conclusion we see that SAPUI5 used properly can boost performance and the framework should be a serious consideration for SAP desktop development, not only making your portal and Business Client look better, but adding the vital user experience factor - performance.

Solving 'Update SAPUI5 Tools and SAPUI5 Team Provider not working in Eclipse because of conflicting dependency'

$
0
0

In the past I have upgraded my Eclipse for SAPUI5 and HANA Studio several times.

This upgrade is not always going well because of conflicting dependency or missing software components.

Triggered by a question from Søren Hansen at SCN, I wrote a paper on sapui.org to solve this problem and want to share this with the SAP community.

 

You can find the paper direct following this link

SAPUI5 project setup for beginners with HTML views - Part1: Installation

$
0
0

Hi all,

 

Starting SAPUI5 development isn't that straightforward as it is for WD ( for example) as an ABAP developer. First of all, developments are in other language called javascript and another environment called eclipse. This is new for most ABAP developers and a basic example of how to setup an SAPUI5 project will boost you all to start with SAPUI5. My intension of this blog is to have one place with all needed information to start developing SAPUI5. This blog will exists out of four parts:

Part1: Installation

Part2: Navigation and storing data with a global model - full project https://github.com/lemaiwo/SAPUI5-part1

Part3: Navigation and storing data with different models - full project https://github.com/lemaiwo/SAPUI5-part2

Part4: Testing your application

 

 

Part1: Installation

  • Install Eclipse
  • Install SAPUI5
  • Download the SAPUI5 SDK
  • Find examples

 

 

Install Eclipse

 

To start developing in SAPUI5, you need some new software. First you need to download eclipse Juno or Kepler:

Juno: http://www.eclipse.org/juno/

Kepler: http://www.eclipse.org/kepler/

 

 

Install SAPUI5

 

The next step is to install SAPUI5 in your eclipse. You can find these steps on: https://tools.hana.ondemand.com/#sapui5

 

In Eclipse, choose in the menu bar Help > Install New Software...

install new software.png


In the Install dialog, enter the following update site URL in the Work with entry field:

 

  • https://tools.hana.ondemand.com/kepler for Eclipse Kepler (4.3)
  • https://tools.hana.ondemand.com/juno for Eclipse Juno (4.2)
  •  

    Press Enter to display the available features.

    Select the desired features under UI Development Toolkit for HTML5 and choose Next.

    select software.png

    On the next wizard page, you get an overview of the features to be installed. Choose Next.

    install details.png

    Confirm the license agreements and choose Finish to start the installation

    license.png

    Installation

    installation.png

    Restart Eclipse:

    restart.png

     

     

    Download the SAPUI5 SDK

     

    After installing SAPUI5, you can download the SAPUI5 SDK at http://scn.sap.com/community/developer-center/front-end.

    sapui5sdkdownload.png

     

     

    Find examples

     

    This is not required for developing SAPUI5 but it has some examples which is very helpful! For example, you have a look a like Fiori application under "test-resources\sap\m\demokit\inbox". (if you are getting errors by testing the example, check part 3. In part3 will be explained how to test a SAPUI5 application)

    example.png

    You can find the "test-resources" after unzipping  HTML5Evaluation_complete_1.16.3_1 and afterworths unzipping the "sapui5-sdk-static" folder. It is possible to browse through all the examples and investigate the source code.

     

    Another reason why I prefer downloading the SDK, the application doesn't need to send a network request to SAP to load the SDK and just uses my local version. Also when SAP upgrades his online SDK, this has no influence on your application.

     

    You can find more helpful information about the SAPUI5 SDK at https://sapui5.hana.ondemand.com/sdk/. This documentation is mostly about JS Views, for HTML views you can find more in the "test-resources".

     

    After everything is installed you can go to the next step and start development!

     

    Next step: Part2: Navigation and storing data with a global model

     

     

    Kind regards,

    Wouter

    SAPUI5 project setup for beginners with HTML views - Part2: Navigation and storing data with a global model

    $
    0
    0

    Hi,

     

    After following SAPUI5 project setup for beginners with HTML views - Part1: Installation you can start with development in SAPUI5. In this blog I'll explain a good way to build your SAPUI5 project with navigation between two views and how to pass data between views.

     

    This blog is the second part of the blog series "SAPUI5 project setup for beginners with HTML views". All different parts:

    Part1: Installation

    Part2: Navigation and storing data with a global model - full project https://github.com/lemaiwo/SAPUI5-part1

    Part3: Navigation and storing data with different models - full project https://github.com/lemaiwo/SAPUI5-part2

    Part4: Testing your application


    Part2: Navigation and storing data with a global model

     

    Overview:

     

    1. Create a SAPUI5 project with a JS View
    2. Create two new HTML Views
    3. Create a javascript file and extend the SAP application object
    4. Change the theme and add the required library's
    5. Instantiate the two views and the navigation in a root View
    6. Add content to the first HTML View and create the functions in the controller
    7. Add  content to the second HTML View and create the functions in the controller
    8. Test the application

     

     

    Create a SAPUI5 project with a JS View

     

    Start with creating your SAPUI5 project

    pic1.png

    pic2.png

    Select Desktop as traget device. The mobile library will be added later to the project later. It’s possible to combine the two library’s.

    pic3.png

    Create a Javascript View, which will be the container for the application.

    pic4.pngpic5.png

     

     

    Create two new HTML Views


    Create two html views, a First view and a Second view. Later in this blog I will pass data between these views.

     

    Starting with the firstview

    pic6.png

    pic7.pngpic8.png

     

     

    Create a javascript file and extend the SAP application object


    After creating these two views, create a javascript file called “Application.js” under the folder WebContent. This file will be used for declaring our global models and instantiate the application container view.


    pic9.png

    pic10.png

    Add the following code to this javascript file:

     

    jQuery.sap.declare("Application");
    jQuery.sap.require("sap.ui.app.Application");
    
    
    sap.ui.app.Application.extend("Application", {
    
    
           init : function() {             // set global models             var model = new sap.ui.model.json.JSONModel();             sap.ui.getCore().setModel(model, "model");       },       main : function() {             // create app view and put to html root element             var root = this.getRoot();             sap.ui.jsview("app", "firstsapui5project.App").placeAt(root);       }
    });

     

    This code defines this file with the name “Application”. So the file can be used with this name. The code loads the SAP version of application, “sap.ui.app.Application”, and then extends it. In the init the global modal is defined which is in currently empty. This could be connected with a gateway service. In the main function the "App" view is pushed to the root div on the index.html which will come in the next step.

     

     

    Change the theme and add the requires library's

     

    In the index.html page is some default SAPUI5 generated content:

         

    <script src="resources/sap-ui-core.js"              id="sap-ui-bootstrap"              data-sap-ui-libs="sap.ui.commons"              data-sap-ui-theme="sap_goldreflection"></script>             <!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required --><script>           sap.ui.localResources("firstsapui5project");           var view = sap.ui.view({id:"idApp1", viewName:"firstsapui5project.App", type:sap.ui.core.mvc.ViewType.JS});           view.placeAt("content");</script>

     

    Delete the second part and start changing the first part where the SDK is defined. In my case I've changed the src to my local version of the SDK. This is two folders up from the index.html page.  The SDK is in the same folder as the project. It has to go two levels up because the index.html page is under the WebContent folder. Instead of the local SDK, it is possible to use the online version and change the src to https://sapui5.hana.ondemand.com/sdk/resources/sap-ui-core.js

     

    pic14.png

     

    Add the sap library’s sap.m and sap.me to data-sap-ui-libs and change the theme to the new Fiori look-a-like design, “Blue Cristal”, in data-sap-ui-theme.

     

    <script src="../../HTML5Evaluation_complete_1.16.3_1/sapui5-sdk-static/resources/sap-ui-core.js"                             id="sap-ui-bootstrap"                              data-sap-ui-libs="sap.ui.commons, sap.m, sap.me"                              data-sap-ui-theme="sap_bluecrystal"></script>

     

    Next step is to load all the files and the Application.js .

    Create an object of the “Application” with the name of the div where the views have to be placed, "content".

     

     

    <script>                              sap.ui.localResources("firstsapui5project");                              //Register your application js                              jQuery.sap.registerModulePath('Application', 'Application');                              // Load your application js                              jQuery.sap.require("Application");                              //Create an object of the Application class and set content as root                              //the DIV content will be used to put the views in                              var app = new Application({ root : "content" });                    </script>

     

     

     

    Instantiate the two views and the navigation in a root View

     

    So far so good, the index.html calls the Application which, again, calls the first view. This view is a jsview which will be used as a container for the application. Now the container view has to be build. Therefore I will copy the content of the App.controller.js and the App.view.js from the inbox application of the mobile demo kit in the test-resources of the SAPUI5 SDK. This is explained in part 1 of this blog: SAPUI5 project setup for beginners with HTML views - Part1: Installation

     

    pic11.png

    In the controller I change the custom part with the views and preferences (such as the transition,…)

    Change the Pages, default page and the first part in getViewName to the name of the folder where all your views are stored.

     

    //=== Custom Part ==================================================================          PAGE : {                    FirstView :                     { type : "HTML",                     app : "App",                    master : undefined },                    SecondView :                     { type : "HTML",                     app : "App",                    master : undefined }          },          getDefaultPage : function() {                    return "FirstView";          },          getViewType : function(pageId) {                    return this.PAGE[pageId].type;          },          getViewName : function(pageId) {                    return "firstsapui5project." + pageId;          },           getAppId : function(pageId) {                    return this.PAGE[pageId].app;          },          isMaster : function(pageId) {                    return this.PAGE[pageId].master;          },          getTransition : function(pageId) {                    if ("App" === this.getAppId(pageId)) {                              return "flip";                    } else if (jQuery.device.is.phone || this.isMaster(pageId)) {                              return "slide";                    } else {                              return "show";                    }          },          isRootInApp: function(pageId) {                    return false;          },          writeToHistory : function(pageId) {                    return true;          },

     

    Everything generic may stay the same and can be reused. This code is used in the application for the navigation between pages. Also add the following at top of the page:

    jQuery.sap.require("sap.m.InstanceManager");

    jQuery.sap.require("jquery.sap.history");

     

    For the App.view.js we add the following code to the method createContent. This is based on the App.view.js from the inbox application in the test-resources.

     

    createContent : function(oController) {                    // to avoid scrollbars on desktop the root view must be set to block display                    this.setDisplayBlock(true);                    // create app control                    this.shell = new sap.m.Shell("Shell", {                              title : "My First SAPUI5 Project"                    });                    this.app = new sap.m.App("App");                    // add only the first page. Second page is lazy loaded                    this.app.addPage(sap.ui.htmlview("FirstView", "firstsapui5project.FirstView"));                    this.app.addPage(sap.ui.htmlview("SecondView", "firstsapui5project.SecondView"));                    this.shell.setApp(this.app);                    // done                    return this.shell;          }

     

    The code instantiate a Shell component and an App component. It also instantiate the two HTML views and add them to the App component. The first view added to the App component will be shown on the screen. In the last step the App component is added to the Shell component and it returns the Shell component.

     

    All available views are instantiated but only the first one is shown. The first parameter to instantiate the htmlview is the name of the view and has to be identically to the name of the PAGE in the App.controller.js. The second parameter is the id of the view which you can find at top of the page of the html view as well in the controller as in the view.

     

     

     

    Add content to the first HTML View and create the functions in the controller

     

    In the first HTML view I've added the following code between the template tags:

     

    <div data-sap-ui-type="sap.m.Page" data-title="First View">                    <div data-sap-ui-aggregation="content">                              <div data-sap-ui-type="sap.ui.commons.form.Form" id="myForm">                                        <div data-sap-ui-aggregation="layout" data-sap-ui-type="sap.ui.commons.form.ResponsiveLayout"id="myLayout"></div>                                        <div data-sap-ui-aggregation="formContainers">                                                  <div data-sap-ui-type="sap.ui.commons.form.FormContainer" id="myInfoContainer" data-title="Form Input">                                                            <div data-sap-ui-aggregation="formElements">                                                            <!-- input field -->                                                                      <div data-sap-ui-type="sap.ui.commons.form.FormElement">                                                                                <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-linebreak="true" data-margin="false"></div>                                                                                <div data-sap-ui-aggregation="label" data-sap-ui-type="sap.m.Label" id="inputLabel" data-text="Input">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "2"></div>                                                                                </div>                                                                                <div data-sap-ui-aggregation="fields" data-sap-ui-type="sap.m.Input" id="inputValue" data-value="{model>/input}">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "8"></div>                                                                                </div>                                                                                <div data-sap-ui-aggregation="fields" data-sap-ui-type="sap.m.Button" id="btn1" data-text="To Second Page" data-tap="secondView">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "2"></div>                                                                                </div>                                                                      </div>                                                            </div>                                                   </div>                                        </div>                              </div>                    </div>                    <div data-sap-ui-aggregation="customHeader">                              <div data-sap-ui-type="sap.m.Bar">                                        <div data-sap-ui-aggregation="contentMiddle">                                                  <div data-sap-ui-type="sap.m.Label" data-text="First View">                                                  </div>                                        </div>                              </div>                    </div>          </div>

     

    The first DIV is to define the page and it is possible to add a title. In this DIV, there are two other parts. ther is the content and the custom header.

    In the custom header I add the bar component with a label in the middle for the title of the first view.

     

    The other part, the content part, is the part which is the main of the application. Here I’ve added a form with responsive layout which contains a label, input and a button.The input field is binded to the global model defined in the Application.js: data-value="{model>/input}"


    In the button we add a tap event: data-tap="secondView"

     

    The method behind this tap event is defined in the controller of the first view:

     

    secondView: function(){                    var bus = sap.ui.getCore().getEventBus();                    bus.publish("nav", "to", {                               id : "SecondView"                    });          }

     

    Use the EventBus to navigate to the SecondView, therefore  the EventBus needs the ID of the view which is defined in App container

     

     

    Add  content to the second HTML View and create the functions in the controller

     

    In the seconde view I've added the following html code between the template tags:

     

    <div data-sap-ui-type="sap.m.Page" data-title="Second View">                    <div data-sap-ui-aggregation="content">                              <div data-sap-ui-type="sap.ui.commons.form.Form" id="myForm">                                        <div data-sap-ui-aggregation="layout" data-sap-ui-type="sap.ui.commons.form.ResponsiveLayout"id="myLayout"></div>                                        <div data-sap-ui-aggregation="formContainers">                                                  <div data-sap-ui-type="sap.ui.commons.form.FormContainer" id="myInfoContainer" data-title="Option 1">                                                            <div data-sap-ui-aggregation="formElements">                                                            <!-- input field -->                                                                      <div data-sap-ui-type="sap.ui.commons.form.FormElement">                                                                                <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-linebreak="true" data-margin="false"></div>                                                                                <div data-sap-ui-aggregation="label" data-sap-ui-type="sap.m.Label" id="inputLabel" data-text="Input">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "2"></div>                                                                                </div>                                                                                <div data-sap-ui-aggregation="fields" data-sap-ui-type="sap.m.Text" id="inputValue" data-text="{model>/input}">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "10"></div>                                                                                </div>                                                                      </div>                                                            </div>                                                   </div>                                        </div>                              </div>                    </div>                    <div data-sap-ui-aggregation="customHeader">                              <div data-sap-ui-type="sap.m.Bar">                                        <div data-sap-ui-aggregation="contentLeft">                                                  <div data-sap-ui-type="sap.m.Button" data-icon="sap-icon://nav-back" data-tap="back">                                                  </div>                                        </div>                                        <div data-sap-ui-aggregation="contentMiddle">                                                  <div data-sap-ui-type="sap.m.Label" data-text="Second View">                                                  </div>                                        </div>                              </div>                    </div>          </div>


     

    This is a comparable to the first view except for the input field. The input field is changed to a text view, but also bound to the global model: data-text="{model>/input}"

     

    In the customHeader I’ve added an back button:

                       <div data-sap-ui-aggregation="contentLeft">                                                  <div data-sap-ui-type="sap.m.Button" data-icon="sap-icon://nav-back" data-tap="back">                                                  </div>                   </div>

     

    In the controller we have to add a function to catch the tap event on the back button:

     

    back: function(){                    var bus = sap.ui.getCore().getEventBus();                    bus.publish("nav", "back");          }

     

     

    Test the application

     

    Now you are ready to test the application. For testing this application there is SAPUI5 project setup for beginners with HTML views - Part4: Testing your application with the required steps:

     

     

    First View:

    pic12.png

    Second View:

    pic13.png

    As you can see the text that we have typed in the first view is visible in the second screen. This is how you can pass data from one view to another. But there are other ways like in the following blog:

     

     

    You can find the full project at https://github.com/lemaiwo/SAPUI5-part1

     

    Next step Part3: Navigation and storing data with different models

     

     

    Kind regards,

    Wouter

    SAPUI5 project setup for beginners with HTML views - Part3: Navigation and storing data with different models

    $
    0
    0

    Hi,

     

    In this blog I'm going to show you how to pass data between views while navigating in a SAPUI5 application. This blog is based on

    SAPUI5 project setup for beginners with HTML views - Part2: Navigation and storing data with a global model

     

     

    It's part 3 of the blog series "SAPUI5 project setup for beginners with HTML views". All different parts:

    Part1: Installation

    Part2: Navigation and storing data with a global model - full project https://github.com/lemaiwo/SAPUI5-part1

    Part3: Navigation and storing data with different models - full project https://github.com/lemaiwo/SAPUI5-part2

    Part4: Testing your application

     

     

    Part3: Navigation and storing data with different models

     

     

    This blog will show you another option for passing data when navigating between views.  In the previous blog I used one global model which was used in both views. In this example I’m going to read the input field from the global model and pass it to the second view. In the second view I add the input field to a second model so it can be used on the view by using the new model.

    I’m starting with what I've already created in the previous blog.

     

     

    Search for the input field in the model:

     

    I start by putting a breakpoint in the controller of the First View before navigating.

    Open my development tools in Google Chrome by pressing F12, go to sources and select the FirstView.controller.js

     

    pic1.png

    Put a breakpoint by clicking in front of the line.

     

    pic2.png

     

    Go to you First View, add some input and press the button. The SAPUI5 application will stop at the breakpoint if the development tools is still open. Now it 's possible to search for the input value by using the console:

     

     

    pic3.png

    With this step we know how to access the input field in the model:

    sap.ui.getCore().getModel("model").oData.input

     

    Change the controller of the First view:

     

    The next step is to extend the application and pass this value to the Second View.

    I’ve changed the navigation in the tap event. I added the parameter data with the value of the input field:

     

    secondView: function(){                    var bus = sap.ui.getCore().getEventBus();                    bus.publish("nav", "to", {                               id : "SecondView",                              data : { input : sap.ui.getCore().getModel("model").oData.input }                    });          }

     

     

    Change the controller of the Second view:

     

    In the second View  controller I add the following code to the init function to register a new method onBeforeShow:

     

    onInit: function() {                    this.getView().addEventDelegate({                              // not added the controller as delegate to avoid controller functions with similar names as the events                              onBeforeShow : jQuery.proxy(function(evt) {                                        this.onBeforeShow(evt);                              }, this)                    });          },

     

     

    I also create a new function, onBeforeShow, where the data that's send from the first view will be read. Nexst step is to instantiat a new model, put the data in it and set this new model as default model for the Second View:

     

    onBeforeShow : function(evt) {                    if (evt) {                              var secondViewModel = new sap.ui.model.json.JSONModel();                              secondViewModel.setData(evt.data);                              this.getView().setModel(secondViewModel);                    }           },

     

     

     

    Change the view of the Second view:

     

    In the view of the Second View I add a second form to show this option next to the option from previous blog Part2: Navigation and storing data with a global model.

     

    <div data-sap-ui-aggregation="formContainers">                                                  <div data-sap-ui-type="sap.ui.commons.form.FormContainer" id="myInfoContainer2" data-title="Option 2">                                                            <div data-sap-ui-aggregation="formElements">                                                            <!-- input field -->                                                                      <div data-sap-ui-type="sap.ui.commons.form.FormElement">                                                                                <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-linebreak="true" data-margin="false"></div>                                                                                <div data-sap-ui-aggregation="label" data-sap-ui-type="sap.m.Label" id="inputLabel2" data-text="Input">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "2"></div>                                                                                </div>                                                                                <div data-sap-ui-aggregation="fields" data-sap-ui-type="sap.m.Text" id="inputValue2" data-text="{/input}">                                                                                          <div data-sap-ui-aggregation="layoutData" data-sap-ui-type="sap.ui.commons.layout.ResponsiveFlowLayoutData" data-weight= "10"></div>                                                                                </div>                                                                      </div>                                                            </div>                                                   </div>                                        </div>

     

    Because the new model is connected to the view, It is possible to just use data-text="{/input}" for binding the value to the view. It automatically uses the model connected to the view.

     

    Result:

     

    pic4.png

     

    pic5.png

     

    Both options work!

     

    You can view the full project at https://github.com/lemaiwo/SAPUI5-part2

     

    Next step Part4: Testing your application

     

    Kind regards,

    Wouter

    SAPUI5 project setup for beginners with HTML views - Part4: Testing your application

    $
    0
    0

    Hi,

     

    This blog is the third part of the blog series "SAPUI5 project setup for beginners with HTML views". All different parts:

    Part1: Installation

    Part2: Navigation and storing data with a global model - full project https://github.com/lemaiwo/SAPUI5-part1

    Part3: Navigation and storing data with different models - full project https://github.com/lemaiwo/SAPUI5-part2

    Part4: Testing your application

     

    Part4: Testing your application

    In the previous parts of this blog I’ve created a sapui5 application. How to test this?

     

    There are two options:

    • Configure chrome
    • Local webserver

    Last but not least there is something about caching.

     

    Configure Chrome

    The first option is to just browse to your project by using your internet explorer or chrome or …

    You copy the path of your project from eclipse:

    pic1.png

     

    Copy the location from the properties

     

    pic2.png

     

    Paste it in your browser

     

    Select WebContent

     

    pic3.png

    Select index.html

     

    pic4.png

     

    But this could give errors:

     

    pic5.png

     

    You can solve this by creating a shortcut of google chrome and add the following to the target property

    --args --allow-file-access-from-files

     

    pic6.png

    But this did not always worked for me…

     

     

    Local webserver

    So another option which I mostly use is a local webserver, XAMPP: http://www.apachefriends.org/en/xampp.html

    Open XAMPP Control Panel and start Apache

     

    pic7.png

    Then copy the project from the workspace to the XAMPP server. The link to the workspace is in the properties of the project. Copy the project and past it in C:\xampp\htdocs.

     

    Now  the application is able to run from the localhost:

    localhost/FirstSAPUI5Project/WebContent/

     

    pic8.png

     

    Caching

    If you do some changes to your application, it is possible that some parts are still cached. A good way to get rid of this caching is opening your development tools in chrome by pressing F12.

     

    In the development tools, go to settings:

     

    pic9.png

     

    Disable cache while DevTools is open:

     

    pic10.png

     

    When Dev tools is open and you refresh the application nothing will be cached. From time to time it could be required to clear cache manually. Press CTRL + SHIFT + DEL:

     

     

    pic11.png

     

    So you are sure that the whole cache is cleared.

     

    Kind regards,

    Wouter


    How to create an SAPUI5 frontend for SAPs Solution Sales Configuration system

    $
    0
    0

    Introduction

     

     

    In this blog I demonstrate how to create an SAPUI5 frontend for SAPs Solution Sales Configuration system.

    SAP Solution Sales Configuration is a system that helps customers to configure and sell solutions made of complex product combinations. It is integrated into both CRM and ECC.

    See here for more details - https://help.sap.com/saphelp_ssc10/helpdata/en/f4/ee271973864f48ad502c070b50ef8a/frameset.htm

    http://www.youtube.com/watch?v=Y3ogJzOtkVA

     

    The UI will be dynamically generated at runtime creating the master lists and detail controls based on the instances and characteristics of the configuration.

    In this application I am using the “sap.m.*” library controls to develop the UI for a mobile solution. For the layout I am using a splitApp control so that I have the master page on the left hand side that will contain a list of instances in the configuration and a detail page on the right hand side which will contain the characteristics of the instances. And of course when run on a mobile device the UI will be split so that you will see either the master page or the detail page. See here for more details on the SplitApp control - https://sapui5.netweaver.ondemand.com/sdk/#docs/guide/SplitApp.html

     

     

    High Level Description

     

    • At a high level I have a js view which creates the splitApp control and a dummy master and detail page which are added to the splitApp (I will explain why I did this later on in the blog).
    • In my web.xml file I defined a servlet mapping for my servlet class SSCServlet which will be the gateway to the SSC engine.
    • In my controller I have an init function which makes a call to the SSCServlet class which in turn calls a java class called SSCClient.
    • The SSCClient will talk to the SSC configuration engine. Firstly it creates a configuration session and then a configuration instance for the knowledge base that I’m using. From this configuration it gets all the instances and instance characteristics.
    • This data is then formatted into a json object to send back to the controller init function via the servlet class.
    • Once the init function receives the json response, it parses out the json and builds out the master and detail pages for the configuration.
    • Each control on the details page will have a change or select event which will call either the onChange or onSelect controller functions.
    • These functions will again send a request to the SSCServlet class to indicate a selection has taken place. The SSCServlet class calls out to the SSCClient class again.
    • The SSCClient sets the new value for the characteristic in the configuration object and via the IDeltaBean object it captures all the configuration changes that have occurred as a result of the characteristic value change.
    • From this IDeltaBean data the class generates a json object with all the changed values and sends this back to the controller functions via the SSCServlet class.
    • In the controller it parses the json response and updates the UI page controls with new values and/or new instances.

     

     

    Details

     

    SSC_UI5_V2.view.js

     

    In the view create the SplitApp control and add a dummy master and detail. The dummy pages are added so that the SplitApp control gets initialized properly. You may run into javascript errors on initialization if not added.

     

    sap.ui.jsview("ssc_ui5_v2.SSC_UI5_V2", {      getControllerName : function() {         return "ssc_ui5_v2.SSC_UI5_V2";      },      createContent : function(oController) {              jQuery.sap.require("jquery.sap.resources");       var oSplit = new sap.m.SplitApp("splitApp");              //Add dummy master and detail pages so that the splitApp gets initialized       var oDummyMaster = new sap.m.Page("dummyMaster");       var oDummyDetail = new sap.m.Page("dummyDetail");                    oSplit.addMasterPage(oDummyMaster);          oSplit.addDetailPage(oDummyDetail);          oSplit.setMode("ShowHideMode");          return oSplit;      }
    });

     

     

    web.xml

     

    In the web.xml define the servlet mapping as follows:

     

    <!-- ============================================================== -->  <!-- SSCServlet servlet                                              -->  <!-- ============================================================== -->    <servlet>    <servlet-name>SSCServlet</servlet-name>    <servlet-class>com.ssc.ui.demo.SSCServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>SSCServlet</servlet-name>    <url-pattern>/SSCServlet/*</url-pattern>  </servlet-mapping>

     

     

    SSC_UI5_V2.controller.js (init function)

     

    On initialization of a SAPUI5 application the onInit function is called. Here we send a request to the SSCServlet URL which was defined in the previous step in the web.xml file. If the call is successful then we should receive a Json response object with the details of what instances and characteristics we need to display in the UI. This Json object is passed to the createUIControls function which will create the controls for the UI.

     

    onInit : function() {  $.ajax({   type : "POST",   url : "SSCServlet",   data : {    command: "initialize"   },   success : function(data) {    sap.ui.controller("ssc_ui5_v2.SSC_UI5_V2").createUIControls(data);   },   error : function(data) {    alert("Failed:" + data);   }  });
     },

     

     

    SSCServlet.java

     

    As stated above the controller init function sends a request to the SSCServlet object and the doGet method is called. The doGet method specifies a json response content type and processes the request. For initialize it calls the getUIElements method of the SSCClient object, and writes the output to the response object.

     

     

    public class SSCServlet extends HttpServlet {
    
     private static final long serialVersionUID = 1L;
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        }
     /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    JsonObjectBuilder objectBuilderOut = Json.createObjectBuilder();    String action = request.getParameter("action");    response.setContentType("application/json");    if (action.equals("initialize"))  {   SSCClient client = new SSCClient();         JsonObject resp = client.getUIElements();   response.getWriter().print(resp);  }  else if (action.equals("change"))  {
    .
    .
    .

     

     

    SSCClient.java

     

     

    When the getUIElements method of the SSCClient is called it calls a number of methods in the SSCClient object to talk to the SSC engine and pull out the instance and characteristic data of the configuration. Here are some of the main features of this code:

     

    • Create a new configuration session:
    IConfigSession cnfgSession = new ConfigSessionLocalImpl();
    cnfgSession.createSession("true", sessionId, dataSourceName, false,    useOnlyLocalDatasource, languageISOCode);

     

    • Create a new configuration from the above session
    String configId = cnfgSession.createConfig(rfcConfigId, productId,      productType, kbLogSys, kbName, kbVersion, kbProfile,      kbIdInt, kbDateStr, kbBuild, useTraceStr, context,      setRichConfigId, useLocalDeltaBean);

     

    • Get the instance data from the configuration session
    IInstanceData[] instData = cnfgSession.getInstances(configId, getMimeObjStr);

     

    • For each instance from the above array we can get the characteristics by calling the getCstics method passing in the config id and the instance id
    ICsticData[] allCstics = cnfgSession.getCstics(configId, instId);

     

    • Using the JsonObjectBuilder we can build up the json objects for the configuration. The properties of the characteristic determine whether the characteristic is to be displayed and what type of control should be used for the characteristic e.g. if you are allowed choose multiple values for a characteristic then create a sap.m.List control with multiSelect mode. Or if it’s single select and there are more than 4 selection values then use a sap.m.Select control, etc…here is an example of this:
    .
    .
    if (csticDat.getCsticVisible()) 
    {
     labelID = csticDat.getCsticHeader().getCsticName() + "Lab"+ inst;
     objectBuilderLabel.add("id", labelID);
     objectBuilderLabel.add("text", csticDat.getCsticHeader().getCsticLname());
     objectBuilderLabel.add("design", "sap.ui.commons.LabelDesign.Bold");  
    
     formEleID = csticDat.getCsticHeader().getCsticName() + "FE"+ inst;
     objectBuilderFormElemProps.add("id", formEleID);
     objectBuilderFormElem.add("properties", objectBuilderFormElemProps);
     objectBuilderFormElem.add("Label", objectBuilderLabel.build());
     objectBuilderFormElem.add("ResponsiveFlowLayoutData", objectBuilderRfld.build());
    
     ICsticValueData[] csticVal = csticDat.getCsticValues();
    
     String val = null;
     if (csticVal != null && csticVal.length > 1 && !csticDat.getCsticDomainIsInterval()) 
     {  if(csticDat.getCsticHeader().getCsticMulti())  {   objectBuilderFormElem.add("List", buildMListJson(csticDat, "sap.m.ListMode.MultiSelect", inst, formEleVarName));   objectBuilderFormElem.add("type", "sap.m.List");   }  else  {   if (csticVal.length>4)   {    objectBuilderFormElem.add("Select", buildMSelectJson(csticDat, true, inst, formEleVarName));    objectBuilderFormElem.add("type", "sap.m.Select");   }
    .
    .
    .

     

    • Once we have built out the Json object for all the instances and characteristics we pass it back to the servlet object which in turns sends the json response back to the calling init function.

     

    SSC_UI5_V2.controller.js (createUIControls function)

     

    The createUIControls function will parse the Json object sent back from the SSCServlet response and build out the UI controls. e.g. - for each object in the "detailPages" json attribute it will create a new Page

     

    if (object == "detailPages")
    { 
     detailPages = data[object];
    
     for ( var page in detailPages)
     {
      newDPage = new sap.m.Page(detailPages[page].properties);

     

     

    For each form element we get the control type and build out the control as specified:

     

      controlType = formElems[elem].type;  switch (controlType)   {   case "sap.m.List":    oCtrlList = new sap.m.List(formElems[elem].List.properties);    switch (formElems[elem].List.mode)    {     case "sap.m.ListMode.MultiSelect":      oCtrlList.setMode(sap.m.ListMode.MultiSelect);      break;     case "sap.m.ListMode.SingleSelect":      oCtrlList.setMode(sap.m.ListMode.SingleSelect);      break;    }    oCtrlListItems = formElems[elem].List.StandardListItem;    for (var listItem in oCtrlListItems)    {     oCtrlList.addItem(new sap.m.StandardListItem(oCtrlListItems[listItem].properties));    }    oCtrlList.attachSelect(sap.ui.controller("ssc_ui5_v2.SSC_UI5_V2").onSelect);    oFormElement.addField(oCtrlList);    break;   case "sap.m.Select":    oCtrlSelect = new sap.m.Select(formElems[elem].Select.properties);    oCtrlSelectItems = formElems[elem].Select.Item;    for (var selectItem in oCtrlSelectItems)    {     oSelectItem = new sap.ui.core.Item(oCtrlSelectItems[selectItem].properties);     oCtrlSelect.addItem(oSelectItem);     if (oSelectItem.getText()== formElems[elem].Select.selectedVal)     {      oCtrlSelect.setSelectedItem(oSelectItem);     }    }    oCtrlSelect.attachChange(sap.ui.controller("ssc_ui5_v2.SSC_UI5_V2").onChange);    oFormElement.addField(oCtrlSelect);    break;

     

    All the form elements are added to a FormContainer. The form container is added to the Form, which is added to the new Page and finally the new page is added to the SplitApp control.

     

     oForm.addFormContainer(oFormContainer);
    
     newDPage.addContent(oForm);
    
     oSplit.addDetailPage(newDPage);
    
    

     

    The master pages are built up in a similar fashion.

     

    At this point the UI is built out with master pages and detail pages. The master pages control the navigation in the UI and are based on the instances of the config and the detail pages contain all the characteristics for each instance.

    The next step was to handle UI events, e.g. a radio button is selected or a list item is selected from a List.

    Each control (sap.m.Select, sap.m.List, sap.m.Input, etc...) will have a change or select event attached to it. These events will send a request to the SSCServlet again passing the change action along with the control that was changed and it's new value.

     

     

    SSC_UI5_V2.controller.js (onSelect function)

     

    onSelect : function(oEvent) {  var control = oEvent.getParameters().id;    var controlValue = oEvent.getParameters().listItem.getTitle();  $.ajax({   type : "POST",   url : "SSCServlet",   data : {    action: "change",    controlKey : control,    controlValueKey : controlValue   },   success : function(data) {    sap.ui.controller("ssc_ui5_v2.SSC_UI5_V2").updateUIControls(data);   },   error : function(data) {    alert("Failed:" + data);   }  });
     },

     

    Again the SSCServlet doGet method processes this request and passes the control and control value to the SSCClient uiChangeEvent method:

     

    SSCClient (uiChangeEvent method)

     

    Some of the main features of this are as follows:

     

    • We define an ICsticData and IDeltaBean object.

     

    ICsticData csticDat = null;
    IDeltaBean csticBean = null;

     

    • The IDeltaBean object is the key here. Once the setCsticsValues method is called then the IDeltaBean object will contain all the changed characteristics and instances that have been generated in the SSC engine as a result of the change in the UI control value.

     

    csticDat.setCsticValues(newCsticVal);
    
    csticBean = setCsticsValues(instId,cnfgSession.getRichConfigId(), false,new ICsticData[] { csticDat }, null, null,0);
    

     

    • Using the IDeltaBean getChangedCsticsAndValues and getNewInstances methods we can get all the changed characteristics and new instances.

     

    HashMap<String, ICsticData[]> changedData = csticBean.getChangedCsticsAndValues();
    ArrayList<IInstanceData> newInstances = csticBean.getNewInstances();

     

    Similarly like we did when generating the json for the intial UI controls we can do the same with the new instances and the changed characteristics. This gets sent back to the onChange or onSelect functions of the controller js via the servlet response. The updateUIControls function is called which parses the json and sets the new values and/or creates the new instance pages and controls.

     

    SSC_UI5_V2.controller.js (updateUIControls function)

     

    The below demonstrates how the new values are set.

     

    for ( var cstic in csticData) 
    {    
     control = sap.ui.getCore().byId(csticData[cstic].CsticName);
     var controlType = control.getMetadata().getName();
     switch (controlType) 
     {  case "sap.m.List":   var allItems = control.getItems();   var newCsticValues = csticData[cstic].csticValues;         var newCsticValue = null;   var newCsticValueAssigned = null;   for ( var csticVal in newCsticValues)    {           newCsticValue = newCsticValues[csticVal].CsticValue;    newCsticValueAssigned = newCsticValues[csticVal].CsticValueAssigned;           for ( var item in allItems)     {     if (allItems[item].getTitle() == newCsticValue)      {      if (newCsticValueAssigned)       {       // check if already selected. if not already selected then select it         if (!allItems[item].getSelected())        {        allItems[item].setSelected(true);       }      }       else       {       // check if already selected. if already selected then deselect it        if (allItems[item].getSelected())        {        allItems[item].setSelected(false);       }      }     }    }   }   break;             case "sap.m.Select":   var allItems = control.getItems();         var newCsticValues = csticData[cstic].csticValues;   var newCsticValue = null;   var newCsticValueAssigned = null;   for ( var csticVal in newCsticValues)    {           newCsticValue = newCsticValues[csticVal].CsticValue;    newCsticValueAssigned = newCsticValues[csticVal].CsticValueAssigned;         for ( var item in allItems)     {             if (allItems[item].getText() == newCsticValue && newCsticValueAssigned)      {      control.setSelectedItem(allItems[item]);      break;     }    }   }   break; 

     

     

     

    To give a flavor of what the knowledge base looks like I have included a few screenshots from the SSC Testing tool:

     

    SSC_VNX_1.png

     

    SSC_VNX_2.png

     

    SSC_VNX_3.png

     

    SSC_VNX_3.png

     

    SSC_VNX_5.png

     

    Note: once the Base Model VNX5200 is selected the engine defaults the Platform configuration and the Rack Selection characteristics. It also creates a new Drive Line instance.

    SSC_VNX_6.png

     

     

     

     

    And here are the screenshots of the UI5 frontend. Notice the master page on the left with the list of instances and the details on the right with the characteristics of the instances.

     

    UI5_1.png

     

    UI5_2.png

     

    UI5_3.png

     

    When Summary Page is selected it navigates to a new master page with a list of all the child instances under the Summary page instance. The navigation button at the top left allows navigation back to the initial master page.

    UI5_4.png

     

    In the VNX Series Solution select VNX5200 for the Base Model

     

    UI5_5.png

     

    The Platform Configuration and Rack Selection are defaulted as indicated below

    UI5_6.png

     

     

    A new Drive Line instance is added to the Storage Components. As Storage Components previously did not have any child instances a new master page is created.

    UI5_7.png

     

    Conclusion

     

    To conclude, the hardest part of the above was figuring out the SSC APIs. Once I was able to pull out the instances and instance characteristics it was relatively straight forward to build up the json object, send it back the UI5 controller and build out the UI from that. The above is just a basic demo and is executed on a local Tomcat instance but gives an idea of what can be done with SAPUI5 as a frontend for SAP Solution Sales Configuration.

    ABAP Icon Library

    $
    0
    0

    Dealing with web frontends, the need of a consistant icon library is crucial. Of course you can use the icons of the SAPUI5 library. But besides this, every SAP ABAP stack also hosts an nice icon library. You can use the following url to have a look at the icons:

     

    http://[HOST][PORT]/sap/bc/bsp/sap/it00/mime_sap_icons.htm

     

    Enjoy

    Patrick

     

    A side note about the SAPUI5 icons: if you ever wondered where all those nice icons come from, you should look out for a true type font called "SAP-Icons.ttf". At first glance, this looks like a regular font file. However, starting with unicode xE000 (57344) there hide all the nice icons. You can make them visible with various tools or simply in Word, where you can use any unicode character by pressing the (decimal) unicode number on the numeric key pad together with the "alt" key.

    13 reasons why SAP should open-source SAPUI5

    $
    0
    0

    BZV3946CUAATKl5.png

    Everyone that has been at a recent SAP Teched, or has come in contact with Fiori in another way, knows that SAP is dead serious about UI5, as the UI development toolkit going forward. At SAP Teched 2013, SAP announced that Fiori Wave 2 gets +150 new apps all based on UI5. Fiori will become the new user experience for a consistent experience across all SAP solutions

     

    More partners and individual developers inside the SAP ecosystem are also trying to adopt UI5, to keep up with the train that SAP has brought to speed. However, because of licensing issues, many partners and developers inside the SAP ecosystem are excluded from boarding this train and also cannot contribute to its velocity. Outside of the SAP ecosystem, it looks even grimmer, as UI5 doesn't even appear on most developer's radar screens yet.

     

    SAP is betting its UX-life on Fiori and UI5. But to make sure that this UI technology is going to be successful and sustainable inside and outside of the SAP ecosystem, something needs to be done. I strongly believe that the answer of its future success lies in open sourcing the UI5 technology, and here are the reasons:

     

    1. Open-Sourcing SAPUI5 is the best way to drive core license revenue

    SAP Core License revenue is on the decline and SAPUI5 provides a renewal of the core that will drive sales of core Finance, HR etc. users, either on-premise or in the cloud.

    Putting barriers in the way to adoption of SAPUI5, like license issues or costs, just puts barriers to customers adopting Fiori and Fiori-esque apps, which will impact core license.

     

    2. To lift legal restriction for use of UI5 by developers outside of the SAP ecosystem

    SAP is trying to advocate to developers outside of the SAP ecosystem to come and try out SAP developer tools and is making a serious effort to show developer that these tools are interesting. It has even setup a developer advisory board with Mohicans from the industry, to advice SAP in this area.

    However, when developers try out SAP's developer tools, they find out that the way they would like to use these tools doesn’t fit in SAP’s legal framework. It is e.g. currently not possible to license UI5 separately, without licensing at least one other Netweaver product.

     

    3. To earn credits in the open source community

    Historically, SAP has been perceived as a rather closed company. Even though the ABAP code has been readable by nature, legal terms prevented you from using it in the same way as open source software is used.

    To appeal to developers in the open source community it needs to shake-off this image. The way this is done in the open source community is by earning respectability and legitimacy first. In the open source community it is important to put your money where your mouth is, not just by lip-service and marketing initiatives, but most importantly by authentic and significant contributions. One step to show real commitment and visibility by SAP would be in open sourcing SAPUI5, and showing up to non-SAP developer conferences to promote it.

     

    4. SAPUI5 has the ideal use-cases for developers outside of the SAP ecosystem

    Other contributions such as the contributions to Eclipse, Virgo and recently OLingo have always flow a bit under the radar because of its limited amount of direct use-cases for most developers. Based on Javascript, and with strong references to UI and UX, UI5 is the central place that would appeal to many developers outside of the SAP ecosystem.

     

    5. To appear on developer's radar screens

    There is a large community of developers that only wants to work with open source options. Without UI5 being open source, it will not even appear on their radar screen.

    The world has changed, and SAP needs to make UI5 much more visible to these communities, rather than concentrating inwardly at existing communities via Sapphire and TechEd events. Making UI5 open source and advocating it at broader developers conferences such as the recent held Devoxx is the way to do that.

     

    6. Because it is legally possible

    Many large corporations have gone before SAP and have released some of their (JavaScript) projects as open source. They have cut the internal red tape, and just went for it. Some of them have been extremely successful:

    • In 2009, AngularJS was released as open source by Google and is mentioned by Infoworld as "a framework to watch" (more)
    • In August, 2011 Twitter released Bootstrap as open source. In February 2012, it was the most popular GitHub development project (more).

    If those other large corporations can do it, SAP should definitely be able to do it too.

     

    7. Because it is in SAP's interest for UI5 to be successful

    UI5 is the go-to framework for SAP. For it to be successful, it needs a wide adoption by developers. When SAP is restricting UI5 to be only available on top of other SAP software, it may very often not be UI of choice. UI5 will lose traction with those developers, as they will continue choosing that other interface technology that they have then become comfortable with.

     

    8. Because it doesn't cost revenue opportunities

    Open sourcing UI5 wouldn't cost SAP revenue. It might mean that SAP would have to tune its market approaches base on open source principles though. In fact, by growing the UI5 ecosystem using the open source band wagon, and adopting the right market approach, revenue may even go through the roof. Have a look at the markets around e.g. Bootstrap and Wordpress etc. to see what SAP could be potentially be missing out on.

     

    9. To tie individual developers as well as partners closer to the SAP ecosystem

    If partners or individual developers want to build an application that would run both on top of an SAP stack as well as the software stack of another vendor, those developers will not be able to freely use UI5, as they can't assume that their customer has the necessary licenses. Those developers will drop UI5 and shift their focus on more broadly adopted offerings in the open market, such as Bootstrap, Sencha and Appcelerator.

    We have seen this happening to Web Dynpro Java already, which was also touted as a technology that would be available for the broader Java audience. However, if you bump into a Java developer, the chances that they will know what Web Dynpro Java are very small.

     

    10. To be able to show UI5 to young developers

    There may be a large opportunity to show UI5 at codeclubs, young rewired state or similar initiatives, as well as at universities to get students familiar with UI5. This has proven to be a success formula for Microsoft, as many of the students that are once familiar with the Microsoft tools, demanded the same tools at their eventual workplace as well.

    For these young students there is no point of learning and tinkering with UI5 though, as chances that there is a legal framework available for it in their future workplace aren't as large as for more broadly adopted offerings by the open market.

     

    11. To prevent being called a leech

    "Leeches" -- that's how Dave Rosenberg, co-founder and former CEO of MuleSource, and now part of the founding team of RiverMuse, refers to companies that use open source technology but don't give back to the open source community (more).

    SAP happily and quietly incorporates impressive amounts of open source contributions such as jQuery (embedded in UI5) and jQuery Mobile (embedded in SUP and Portal on Device) into its products. Although it is legally sound, it may not lead to the right perception by the open source community. It would be great to see the contribution going the other way in just as significant and visible a manner.

     

    12. To progress faster and serve customers better

    If UI5 would be open sourced and would find the traction that other open source projects have seen, SAP can expect contributions to UI5 from the open source community as well. It can count on improvements and added features that it perhaps would have on the roadmap already. But it is also quite likely that additional features coming straight from customers would be added as well. It would also see features added that would allow UI5 to run in more environments and architectures than only those ones based on an SAP tool-stack.

     

    13. Open Sourcing UI5, would be a next step in opening up the corporate culture of SAP

    By creating an open culture, you spark innovation, decrease fear of failure and inspire open collaboration. An open culture is opposed to a culture of secrecy and confidentiality. Although SAP is trying to polish up their image and look like they are more open, most part of company is still very much closed.

     

    When would be a good moment?

    Now would be agreeable to me...

    But on a serious note, it needs to be done fast, as UI5 is not the only interface technology around at this moment, and UI5 may lose the traction it needs, both inside as well as outside the SAP ecosystem because of reasons mentioned earlier.

    On top of that, there are rumors about country sales organisations that have started charging money for UI5. If UI5 is ever going to be open sourced, those customers may feel robbed in the end.

     

    Being an extensible and hopefully an open framework, SAPUI5 has all the potential to gain momentum as the enterprise-ready, solid UI framework of choice, on top of both SAP as well as non-SAP applications. A wise decision needs to be made soon though.

     

    Call to action

    If you also think that SAP should open-source UI5, please do leave a little response behind to show your support. I am hoping that SAP would be sensitive to a widespread support of the idea.

     

    Credits

    In the good spirit of open source, this blog has been formed and shaped by a lot of contributions, opinions and comments by many people from the community. I may have forgotten some, but here's a list of people that have contributed directly or indirectly: Ethan Jewett, DJ Adams, Robin van het Hof, Nigel James,John Patterson, Chris Paine, John Moy, Gavin Quinn, Phil Loewen, Leo van Hengel, John Appleby, Helmut Tammen, Uwe Fetzer, Robert Eijpe, Tom Van Doorslaer (please do let me know if I missed out on anyone).

    How to use Maven to build your SAPUI5 application

    $
    0
    0

     

    Introduction

    At the moment I am working as a QA officer on a SAPUI5 project at a customer. The customer has a development and QA environment containing Jenkins for CI and Sonar for quality inspection. As a QA officer I want to use these tools to ensure code quality. To be able to do so I needed to convert my standard SAPUI5 project to a Maven project. Below is a step by step guide how I achieved this.

    Install Maven

    Installing Maven is pretty straight forward. Follow the link below and you should be ready to start in five minutes:

     

    http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

     

    Install SAPUI5 Eclipse Plugin

     

    • Download the latest version: http://scn.sap.com/community/developer-center/front-end , at the time of writing this was version 1.16.3
    • Howto install in eclipse
      • Extract folder “tools-updatesite”
      • Open eclipse -> Help -> Install New Software…
      • Select “Add…” -> “Local…” -> Browse to the “tools-updatesite” folder

    Add SAPUI5 libraries to local Maven repository

    To be able to use SAPUI5 libraries with Maven you have to add the jar files to your local Maven repository. If you use Nexus as a repository you can add the jar files there. For this example the jar files are added locally.Open a command prompt and cd to the “\tools-updatesite\plugins” folder. Execute the following commands (version numbers may vary):


    • mvn install:install-file -Dfile=com.sap.ui5.core_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.core -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.commons_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.commons -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.table_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.table -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.ux3_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.ux3 -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.visualization_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.visualization -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.richtexteditor_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.richtexteditor -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.mobile_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.mobile -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.makit_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.makit -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.viz_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.viz -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.mobile-ext_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.mobile-ext -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.themelib_sap_goldreflection_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.themelib_sap_goldreflection -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.themelib_sap_ux_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.themelib_sap_ux -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.suite.suite-ui-commons_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.suite.suite-ui-commons -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.resource_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.resource -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.utils_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.utils -Dversion=1.16.3 -Dpackaging=jar
    • mvn install:install-file -Dfile=com.sap.ui5.layout_1.16.3.jar -DgroupId=com.sap.ui5 -DartifactId=com.sap.ui5.layout -Dversion=1.16.3 -Dpackaging=jar

    Create POM

    A POM file has to be created to be able to build the project and to be able to create an eclipse project for it. Also a “org.eclipse.wst.common.project.facet.core.xml” should be created in the .settings folder in your project if you want to share the project using a version control system (like SVN). This file describes the project facets to use. In my project I have started with a standard SAPUI5 application project and added the files in the project folder. I have attached both files as a reference.

     

    Build

    Now that everything is in place the project war file can be built, this is done by executing the following command:

    “mvn clean install package”

     

    Create eclipse project <optional>

    This is an optional step. If you want to use eclipse as your IDE and share the project using a version control system you don’t want to checkin your project definition files. When you have checked out the project execute the following command to create a project definition file:

    “mvn eclipse:eclipse”

    This creates a project for you which you can import in Eclipse. After you import the project you still have to convert the project to faceted form by opening the project properties:


     

    After selecting “Convert to faceted form…” you have to deselect “SAPUI5 application” from the list and press “Apply”. This will update your project to use the facets. Unfortunately the SAPUI5 facet only works if it was deselected first.

     

     

    After pressing “Apply” you can now select the “SAPUI5 application” item from the list and press “Apply” again.

     

     

    Now you can run your application with “Web App Preview” which was not available before.


     

    Congratulations, you are now ready to use Maven to build your project!


    CodeTalk: SAPUI5 and SAP Fiori

    $
    0
    0

    Yesterday I was honoured to be a guest on Ian Thain 's CodeTalk series of video interviews. The subject was SAPUI5 and SAP Fiori, and the published interview is split over two videos on YouTube. Here's what we covered, based on the questions asked.

     

    Video Playlist: https://www.youtube.com/playlist?list=PLfctWmgNyOIcae85Ytr6b_J1jgcDb4-JL

     

    Part 1

     


    In this part, we discuss SAPUI5 and SAP Fiori in general, and talk about the relation between these two things, major features in SAPUI5, including the automatic module loading system, the data model mechanisms, and in particular OData. We also talk about the architecture and startup of a very simple app.

     

    Questions covered:


    • What is SAPUI5, where is it positioned, and where is it being used right now?
    • What does SAPUI5 consist of?
    • What does SAPUI5 look like?
    • Can you give me an overview of some of the major features of SAPUI5?
    • Can you tell me more about OData and SAPUI5?
    • What is Fiori?
    • What does a basic app look like?

     

    Part 2

     

     

    In this part we dig a little deeper, and talk about what a more complex app looks like. There's an example custom Fiori app, built using the Component concept and there's an 11 minute screencast that walks through that app, the controls used, and then looks under the hood to see how it's put together (bootstrap, parameters, Component and ComponentContainer, index.html, Component.js, views (JavaScript & XML) and controllers, View containing the SplitApp control, custom utility functions, internationalisation, folder structure, and more).

     

    Further questions covered:

     

    • What does a more complete app look like?
    • What skills do I need?
    • What are the next steps?

     

    If you just want a future reference to the screencast, it's available separately here too: https://www.youtube.com/watch?v=tfOO4szA2Bg

     

    Share and enjoy!

    Why I want my Fiori to run like a Ferrari

    $
    0
    0

    Ever since SAP announced the release of Fiori earlier this year I've been excited by the prospect of a renaissance in SAP's UX/UI future.  The apps look gorgeous and the fact that they are positioned around HTML5 technologies (SAPUI5) and multi-channel support (eg. smartphones, tablets, desktops) makes them well positioned for the future.

     

    Fiori_image.png

     

     

    And I was further impressed to see SAP make bold statements such as this one when I attended SAP TechEd 2013 in Las Vegas (the below from the session 'TEC149 - SAP UX Strategy and UI Roadmap') ...

     

    "All applications & UI technologies to converge to the Fiori concept.  The roadmap beyond the initial Suite applications is yet to be defined."

     

    (Source: Slide TEC149 page 62, SAP TechEd 2013 Las Vegas)

     

    Oh, let's not forget the fine print ... "This is the current state of planning and may be changed by SAP at any time".

     

    But ever since I saw the first live demonstration of Fiori apps by an SAP representative, there is one thing that I've been a little uneasy about, and its this ... I noticed it took a fair amount of time (and by that I mean well over 10 seconds) for the app to appear on a mobile device after being launched.  And I cast my mind back over a decade to the words of the usability guru Dr Jakob Nielson in his book 'Designing Web Usability' from 1999, where he makes this important observation based on usability studies ...

     

    "Download times rule the Web, and since most users have access speeds on the order of 28.8 kbps, Web pages can be no more than 3 KB if they are to download in one second .... Users do not keep their attention on the page if downloading exceeds 10 seconds, corresponding to 30 KB at modem speed. "

     

    Source: Dr Jacob Nielson, 'Designing Web Usability' 1999

     

    Now of course over a decade on from those observations, we no longer operate in a world of modems or 30KB websites.  Yet the world of mobile and slow or brittle networks has brought back similar challenges, and once again we need to be mindful of the need for lean web delivery.  Indeed some have taken it a little far with statements such as this (below someone quoting on Twitter what they heard at a conference) ...

     

    "You should never use a JavaScript library that you couldn't store in the RAM of a Commodore 64." (Source: unknown)

     

    On a side note ... if you are my vintage, you may remember that whilst a Commodore 64 had 64K or RAM, the available amount for the user was only 38K.  And if you want to be really nostalgic, try out this Commodore 64 emulator that someone wrote in HTML5 and JavaScript http://www.kingsquare.nl/jsc64.  But back to my point ...

     

    The current literature on the web describes Fiori as a set of 'lightweight' consumer-friendly applications from SAP.  But my anecdotal observations had me asking myself just how lightweight are these apps, from a client payload perspective?  So, I have had debates recently about how lean the Fiori apps (and the underlying SAPUI5 libraries) really are.  Or more accurately whether they should be leaner to improve the time to load Fiori app resources into the browser, and by extension improve the user experience.  Of course, that's easier said than done when you want to build in a wealth of 'enterprise-grade' features ... but that is the challenge for the engineers at SAP to tackle.

     

    I discussed this with Njål Stabell from Neptune Software who I met at TechEd and has deep experience with SAPUI5.  He wrote a blog providing his analysis of how a custom SAPUI5 app would outperform an equivalent Web Dynpro ABAP app here ... Performance comparison of ABAP WebDynpro and SAPUI5 with Neptune Application Designer.  But what was still missing was an analysis of Fiori apps against the equivalent Web Dynpro ABAP counterparts.

     

    So recently I had the opportunity to implement some SAP Fiori apps for trial purposes, and at the same time measure such things as the performance and download size of the apps.  I was also able to compare against the equivalent Web Dynpro ABAP app provided by SAP.  Here are my findings...

     


    Firstly I examined the payload to download the out-of-box SAP Fiori leave request app to a browser with an empty cache. 

     

    Fiori leave request payload 1.png

     

    In the above test (which I repeated half a dozen times) I noticed that a whopping 1MB (after 72% compression) of download with 84 separate HTTP requests is received the first time a browser attempts to render the Fiori leave request app.  Similar measurements were obtained for others, such as the leave approval app. In the above test the payload takes 14 seconds to retrieve over a high speed LAN.  However I also tested the worst case (which mobiles can sometimes exhibit) ... satellite access with 600ms latency.  In this worst case scenario, the download took closer to 100 seconds to retrieve.

     

     

    Next I examined the payload to download the equivalent out-of-box Web Dynpro ABAP leave request app with an empty browser cache.

     

    WDA leave request payload 1.png

     

    So the Web Dynpro ABAP leave request app delivered by SAP renders with around 280K of payload over 65 HTTP requests.  In the above test the data takes 9 seconds to retrieve. 

     

    Effectively the Fiori leave app had a payload of almost four times that of the equivalent Web Dynpro ABAP leave app, with almost 30% more HTTP requests.  When the browser cache is full (ie. after first load), performance for both the Fiori app and Web Dynpro app is much better.

     

     

     

    What I want to see in Fiori

     

    I am an advocate of HTML5 (see my recent presentation on it) and by extension I believe that SAP's foray into HTML5-based apps with Fiori and SAPUI5 is the appropriate approach, especially when combined with pace layering enablers such as NetWeaver Gateway. However, here's what I would like to see in Fiori ...

     

    Basically, we find that whilst this first release of Fiori apps brings gorgeous design and an appropriate way forward, more attention needs to be paid to the user experience from the perspective of time to load the app.  All is well if you operate with fast networks to desktops.  But if serving these apps to remote locations or mobile devices, then other measures (eg. wrapping the Fiori apps in PhoneGap or SAP's Kapsel) may be necessary (with the associated complexities and costs, such as potentially implementing SAP Mobile Platform if the use of Kapsel is desired).  In fact, that may explain why in recent SAP demonstrations of Fiori on mobiles, I have seen SAP demo with precisely this wrapping implemented - there is no initial delay in rendering the app.  Of course, when comparing with SAP's Web Dynpro ABAP we are looking at a much more mature technology.  And SAP sought to optimise WDA over time ... such as with the introduction of lightspeed rendering. (and in an ironic twist, Andreas Kunz tells me the original codename for SAPUI5 was 'Phoenix', and that name was derived based on what is faster than light speed .... being warp speed, which any Trekkers amongst you know was achieved by the spaceship Phoenix in the movie 'Star Trek: First Contact').

     

    What would I like SAP to do? Well, provide a mechanism in the ICF to only serve what is necessary, and to consolidate resources to minimise HTTP requests and minify resources. For instance, a mechanism to automatically combine and minify JavaScript and CSS files etc.  Don't think it is possible?  Well Google engineers pulled it off with their open source contribution of Google PageSpeed Module for Apache and Nginx web servers.  So I'm sure SAP's engineers would be equally capable.  Or the open source community might.  In fact in the blog 13 reasons why SAP should open-source SAPUI5 by Jan Penninkhof there is a similar comment provided by M.Saad Siddiqui...

     

    Blog comment.png

    In the course of research for this blog I noticed also similar concerns were raised by Tobias Hofmann in this blog ... Remember, all I'm offering is the truth – nothing more – week 5

     

     

    So there we have it.  Fiori delivers great looking apps. But from my perspective, if SAP is to be successful in the long run with Fiori, it needs to be lean, fast, and perfectly tuned for the environment it is built for .... to run better, like a Ferrari!  Lets hope SAP can take us there ..... fast.

     


    SAPUI5: PDF Scrolling on iPad

    $
    0
    0

    Hi all,

     

    just wanted to share results of SAPUI5 digging evening.

     

    Its all started by the reading of question on sdn PDF Viewer for SAPUI5 Application

    The issue was, that embedded PDF-File is not able to be scrolled on ipad.

     

    After first investigation it was clear, that scrolling of iview is a common issue on ios devices. So, the challenge was to find a workaround.

    For test application I decided to use a SplitApp from sap.m library.

     

    Here is a draft design of the application.

    sapPDF.001.jpg

    I decided not to use MVC just to reduce number of files for this example.

    So the structure of the project just looks like following

    structure.png

    Actually only 2 files needed: index.html and pdf file to display.

     

    Here is a source code of index html with explanation.

     

    <!DOCTYPE HTML><html><head>  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <script src="resources/sap-ui-core.js"  id="sap-ui-bootstrap"  data-sap-ui-libs="sap.m"  data-sap-ui-theme="sap_bluecrystal">  </script>  <script>                              function setPDFHeight(){                                        $("#pdfObject")[0].height = $("#pdfObject")[0].offsetHeight;                               }                               var oApp = new sap.m.SplitApp( "splitApp" ); // Split                              var oMaster = new sap.m.List( "mList" );                              oApp.addMasterPage(oMaster);                              var oPage = new sap.m.Page({                                        id : "mPage",                                         showHeader : false,                                         enableScrolling : false, // !!!! Important !!!!                                        showFooter : false                              });                              var oHTML = new sap.ui.core.HTML("iFRM");                               oHTML.setContent("<div align=\"center\" style=\"width: 100%; height:100%; overflow: auto !important; -webkit-overflow-scrolling: touch !important;\"><object id=\"pdfObject\" width=\"100%\" height=\"1000000000000\" align=\"center\" data=\"pdf/HANADevGuide.pdf\" type=\"application/pdf\" onload=\"setPDFHeight()\">You have no plugin installed</object></div>");                              oPage.addContent(oHTML);                              oApp.addDetailPage(oPage);                              oApp.placeAt("content")  </script></head><body class="sapUiBody" role="application">  <div id="content"></div></body></html>

     

    What I got from googling is that scrollable content must be wrapped into div with following style properties (I defined these properties as !important):

     

    overflow: auto;

    -webkit-overflow-scrolling: touch;

     

    Another fix is to define a detail page as non scrollable (enableScrolling : false)

     

    Third fix was to use not an iframe (I could not get it functional) but the object. So it was necessary to auto-resize height of the object (object height must be taken from PDF-height).

     

    for that purpose I have used a function setPDFHeight(), which was assigned to onload event of the object.

     

    And the last but not least fix was an initial height of PDF-Object. To get the correct value of offsetHeight attribute the initial height must be more, than height of PDF document. I just set it to  1000000000000.

     

    As a result I got scrollable PDF document on iPad.

     

    iPad2:

    ipad2.png

     

    iPadAir:

    ipadair.png

     

     

    P.S.:  English language is not my native language, and any person is not insured from mistakes and typing errors. If you have found an error in the text, please let me know.

    P.P.S.: If you have some ideas, how to correct/improve the code - please don't hesitate to leave a comment.


    Custom Sorting and Grouping

    $
    0
    0

    Summary: Learn how to control the order of groups in a sorted list. You don't do it directly with the grouper function, you do it with the sorter function.

     

    One of the features of the app that the participants build in the CD168 sessions at SAP TechEd Amsterdam is a list of sales orders that can be grouped according to status or price (the screenshot shows the orders grouped by price).

     

    groupbyprice.PNGThis is achieved by specifying a value for the vGroup parameter on the Sorter, as documented in the sap.ui.model.Sorter API reference:

     

    Configure grouping of the content, can either be true to enable grouping based on the raw model property value, or a function which calculates the group value out of the context (e.g. oContext.getProperty("date").getYear() for year grouping). The control needs to implement the grouping behaviour for the aggregation which you want to group.

     

    So what this means is that you either specify a boolean true value, or the name of a function.

     

    - use a boolean true to have the entries grouped "naturally" by their value: useful and useable where you have texts that will be the same for some entries

     

    - specify the name of a function that will do some custom grouping: useful where you have numeric values that you might want to group into sizes or ranges

     

    Here in the example in the screenshot on the left, we're using a custom grouper function to arrange the sales orders into value groups (less than EUR 5000, less than EUR 10,000 and more than EUR 10,000).

     

     

     

     

    Group Order Challenge

     

    But what if you wanted to influence not only the sort but also the order of the groups themselves? Specifically in this screenshot example, what if we wanted to have the "< 5000 EUR" group appear first, then the "> 10,000 EUR" group and finally the "< 10,000 EUR" group? (This is a somewhat contrived example but you get the idea). This very question is one I was asking myself while preparing for the CD168 session, and also one I was asked by an attendee.

     

    To understand how to do it, you have to understand that the relationship between the sorter and the grouper can be seen as a "master / slave" relationship. This is in fact reflected in how you specify the grouper - as a subordinate of the master.

     

    The sorter drives everything, and the grouper just gets a chance to come along for the ride.

     

    So to answer the question, and to illustrate it in code step by step, I've put together an example. It takes a simple list of numbers 1 to 30 and displays them in a list, and groups them into three size categories. You can specify in which order the groups appear, but the key mechanism to achieve this, as you'll see, is actually in the sorter.

     

     

     

    Simple and Complex Sorting

     

    To understand further, you have to remember that there's a simple sorter specification and a more complex one. Using a simple sorter is often the case, and you'd specify it like this:

     

    new sap.m.List("list", {    items: {        path: '/records',        template: new sap.m.StandardListItem({            title: '{amount}'        }),        sorter: new sap.ui.model.Sorter("amount") // <---    }
    })

     

    This is nice and simple and sorts based on the value of the amount property, default ascending.

     

    The complex sorter is where you can specify your own custom sorting logic, and you do that by creating an instance of a Sorter and then specifying your custom logic for the fnCompare function.

     

    We'll be using the sorter with its own custom sorting logic.

     

     

     

    Step By Step

    So here's the example, described step by step. It's also available as a Gist on Github: Custom Sorter and Grouper in SAPUI5 and exposed in a runtime context using the bl.ocks.org facility: http://bl.ocks.org/qmacro/7702371

     

    As the source code is available in the Gist, I won't bother showing you the HTML and SAPUI5 bootstrap, I'll just explain the main code base.

     

     

            var sSM = 10;  // < 10  Small        var sML = 15;  // < 15  Medium                                  //    15+ Large

     

    Here we just specify the boundary values for chunking our items up into groups. Anything less than 10 is "Small", less than 15 is "Medium", otherwise it's "Large". I've deliberately chosen groupings that are not of equal size (the range is 1-30) just for a better visual example effect.

     

     

     

            // Generate the list of numbers and assign to a model        var aValues = [];        for (var i = 0; i < 30; i++) aValues.push(i);        sap.ui.getCore().setModel(            new sap.ui.model.json.JSONModel({                records: aValues.map(function(v) { return { value: v }; })            })        );

     

    So we generate a list of numbers (I was really missing Python's xrange here, apropo of nothing!) and add it as a model to the core.

     

     

     

            // Sort order and title texts of the S/M/L groups        var mGroupInfo = {            S: { order: 2, text: "Small"},            M: { order: 1, text: "Medium"},            L: { order: 3, text: "Large"}        }

     

    Here I've created a map object that specifies the order in which the Small, Medium and Large groups should appear in the list (Medium first, then Small, then Large). The texts are what should be displayed in the group subheader/dividers in the list display.

     

     

     

            // Returns to what group (S/M/L) a value belongs        var fGroup = function(v) {            return v < sSM ? "S" : v < sML ? "M" : "L";        }

     

    This is just a helper function to return which size category (S, M or L) a given value belongs to.

     

     

     

            // Grouper function to be supplied as 3rd parm to Sorter        // Note that it uses the mGroupInfo, as does the Sorter        var fGrouper = function(oContext) {            var v = oContext.getProperty("value");            var group = fGroup(v);            return { key: group, text: mGroupInfo[group].text };        }

     

    Here's our custom Grouper function that will be supplied as the third parameter to the Sorter. It pulls the value of the property from the context object it receives, uses the fGroup function (above) to determine the size category, and then returns what a group function should return - an object with key and text properties that are then used in the display of the bound items.

     

     

            // The Sorter, with a custom compare function, and the Grouper        var oSorter = new sap.ui.model.Sorter("value", null, fGrouper);        oSorter.fnCompare = function(a, b) {            // Determine the group and group order            var agroup = mGroupInfo[fGroup(a)].order;            var bgroup = mGroupInfo[fGroup(b)].order;            // Return sort result, by group ...            if (agroup < bgroup) return -1;            if (agroup > bgroup) return  1;             // ... and then within group (when relevant)            if (a < b) return -1;            if (a == b) return 0;            if (a > b) return  1;        }

     

    Here's our custom Sorter. We create one as normal, specifying the fact that we want the "value" property to be the basis of our sorting. The 'null' is specified in the ascending/descending position (default is ascending), and then we specify our Grouper function. Remember, the grouper just hitches a ride on the sorter.

     

    Because we want to influence the sort order of the groups as well as the order of the items within each group, we have to determine to what group each of the two values to be compared belong. If the groups are different, we just return the sort result (-1 or 1) at the group level. But if the two values are in the same group then we have to make sure that the sort result is returned for the items themselves.

     

     

            // Simple List in a Page        new sap.m.App({            pages: [                new sap.m.Page({                    title: "Sorted Groupings",                    content: [                        new sap.m.List("list", {                            items: {                                path: '/records',                                template: new sap.m.StandardListItem({                                    title: '{value}'                                }),                                sorter: oSorter                            }                        })                    ]                })            ]        }).placeAt("content");

     

    And that's pretty much it. Once we've done the hard work of writing our custom sorting logic, and shared the group determination between the Sorter and the Grouper (DRY!) we can just specify the custom Sorter in our binding of the items.

     

    And presto! We have what we want - a sorted list of items, grouped, and those groups also in an order that we specify.

     

    sortedgroupings.PNG

     

     

    Post Script

     

    There was a comment on this post which was very interesting and described a situation where you want to sort, and group, based on different properties. This is also possible. To achieve sorting on one property and grouping based on another, you have to recall that you can pass either a single Sorter object or an array of them, in the binding.

     

    So let's say you have an array of records in your data model, and these records have a "beerName" and a "beerType" property. You want to group by beerType, and within beerType you want the actual beerNames sorted.

     

    In this case, you could have two Sorters: One for the beerType, with a Grouper function, and another for the beerName. Like this:

     

            var fGrouper = function(oContext) {            var sType = oContext.getProperty("beerType") || "Undefined";            return { key: sType, value: sType }        }        new sap.m.App({            pages: [                new sap.m.Page({                    title: "Craft Beer",                    content: [                        new sap.m.List("list", {                            items: {                                path: '/',                                template: new sap.m.StandardListItem({                                    title: "{beerName}",                                    description: "{beerType}"                                }),                                sorter: [                                    new sap.ui.model.Sorter("beerType", null, fGrouper),                                    new sap.ui.model.Sorter("beerName", null, null)                                ]                            }                        })                    ]                })            ]        }).placeAt("content");

    I've put a complete example together for this, and it's in the sapui5bin Github repo here:

     

    sapui5bin/SortingAndGrouping/TwoProperties.html at master · qmacro/sapui5bin · GitHub

     

    And while we're on the subject of code examples, there's a complete example for the main theme of this post here:

     

    sapui5bin/SortingAndGrouping/SingleProperty.html at master · qmacro/sapui5bin · GitHub

        

    Share & enjoy!

    Open Source SAPUI5 - Got the T-Shirt?

    $
    0
    0

    Recently there has been a growing movement within the SAP Community to make a case for open sourcing the UI Development Toolkit for HTML5 aka SAPUI5. I won't rehash all the arguments again here but instead point you to this great post 13 reasons why SAP should open-source SAPUI5 by Jan Penninkhof who has brought all the reasons together very nicely.

     

    So I thought why don't we create a t-shirt to promote this idea and show some support - plus it makes a great geeky holiday gift with the holidays just around the corner. It needs at least 50 people to buy the shirt for it to go into print - you only get charged if it hits that number. You can buy the t-shirt here:

     

    http://teespring.com/sapui5

     

    http://images.teespring.com/uploads/2013/11/28/22/181874/shirtFront.jpg?v=2013-12-01-21-47http://images.teespring.com/uploads/2013/11/28/22/181874/shirtBack.jpg?v=2013-12-01-21-47

     

    Just to be clear, the goal isn't to make money from this, so the shirts are being sold at cost - the goal is to highlight this community initiative and have some fun.

     

    Thanks,

    Simon

    Mobile Dev Course W3U3 Rewrite - XML Views - An Analysis

    $
    0
    0

    I rewrote the mobile dev course sample app from W3U3. Then I created a new branch 'xmlviews' in the repo on Github and rebuilt the views in XML. I then took a first look at XML views in general. Now this post looks at the specific XML views that I built in the W3U3 rewrite. See the links at the bottom of the opening post of this series to get to explanations for the other areas.

     

    We know, from the other posts in this series, that there are a number of views. Let's just take them one by one. If you want an introduction to XML views, please refer to the previous post Mobile Dev Course W3U3 Rewrite - XML Views - An Intro. I won't cover the basics here.

     

     

    App View

     

    The App view contains an App control (sap.m.App) which contains, in the pages aggregation, the rest of the views - the ones that are visible. This is what the App view looks like in XML.

     

    <?xml version="1.0" encoding="UTF-8" ?><core:View controllerName="com.opensap.App" xmlns:core="sap.ui.core"    xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">    <App id="app">        <mvc:XMLView viewName="com.opensap.Login" id="Login" />        <mvc:XMLView viewName="com.opensap.ProductList" id="ProductList" />        <mvc:XMLView viewName="com.opensap.ProductDetail" id="ProductDetail" />        <mvc:XMLView viewName="com.opensap.SupplierDetail" id="SupplierDetail" />    </App></core:View>

    We're aggregating four views in the App control (introduced by the <App> tag). Because the pages aggregation is the default, we don't have to wrap the child views in a <pages> ... </pages> element. Views and the MVC concept belong in the sap.ui.core library, hence the xmlns:core namespace prefix usage.

     

     

    Login View

     

    The Login view contains, within a Page control, a user and password field, and a login button in the bar at the bottom. This is what the XML view looks like.

     

    <?xml version="1.0" encoding="UTF-8" ?><core:View controllerName="com.opensap.Login" xmlns:core="sap.ui.core"    xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">    <Page        title="Login"        showNavButton="false">        <footer>            <Bar>                <contentMiddle>                    <Button                        text="Login"                        press="loginPress" />                </contentMiddle>            </Bar>        </footer>        <List>            <InputListItem label="Username">                <Input value="{app>/Username}" />            </InputListItem>            <InputListItem label="Password">                <Input value="{app>/Password}" type="Password" />            </InputListItem>        </List>    </Page></core:View>

    You can see that the Page control is the 'root' control here, and there are a couple of properties set (title and showNavButton) along with the footer aggregation and the main content. Note that as this is not JavaScript, values that you think might appear "bare" are still specified as strings - showNavButton="false" is a good example of this.

     

    The Page's footer aggregation expects a Bar control, and that's what we have here. In turn, the Bar control has three aggregations that have different horizontal positions, currently left, middle and right. We're using the contentMiddle aggregation to contain the Button control. Note that the Button control's press handler "loginPress" is specified simply; by default the controller object is passed as the context for "this". You don't need to try and engineer something that you might have seen in JavaScript, like this:

     

    new sap.m.Button({     text: "Login",     press: [oController.loginPress, oController]
    }),

    ... it's done automatically for you.

     

    Note also that we can use data binding syntax in the XML element attributes just like we'd expect to be able to, for example value="{app>/Username}".

     

     

    ProductList View

     

    In the ProductList view, the products in the ProductCollection are displayed. There's a couple of things that are worth highlighting in this view. First, let's have a look at the whole thing.

     

    <?xml version="1.0" encoding="UTF-8" ?><core:View controllerName="com.opensap.ProductList" xmlns:core="sap.ui.core"    xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">    <Page        title="Products">        <List            headerText="Product Overview"            items="{                path: '/ProductCollection'            }">            <StandardListItem                title="{Name}"                description="{Description}"                type="Navigation"                press="handleProductListItemPress" />        </List>    </Page></core:View>

    The List control is aggregating the items in the ProductCollection in the data model. Note how the aggregation is specified in the items attribute - it's pretty much the same syntax as you'd have in JavaScript, here with the 'path' parameter. The only difference is that it's specified as an object inside a string, rather than an object directly:

     

    items="{                path: '/ProductCollection'            }"

    So remember get your quoting (single, double) right.

     

    And then we have the template, the "stamp" which we use to produce a nice visible instantiation of each of the entries in the ProductCollection. This is specifiied in the default aggregation 'items', which, as it's default, I've omitted here.

     

     

    ProductDetail View

     

    By now I'm sure you're starting to see the pattern, and also the benefit of writing views in XML. It just makes a lot of sense, at least to me. It's cleaner, it makes you focus purely on the controls, and also by inference causes you to properly separate your view and controller concerns. You don't even have the option, let alone the temptation, to write event handling code in here.

     

    So here's the ProductDetail view.

     

    <?xml version="1.0" encoding="UTF-8" ?><core:View controllerName="com.opensap.ProductDetail" xmlns:core="sap.ui.core"    xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">    <Page        title="{Name}"        showNavButton="true"        navButtonPress="handleNavButtonPress">        <List>            <DisplayListItem label="Name" value="{Name}" />            <DisplayListItem label="Description" value="{Description}" />            <DisplayListItem label="Price" value="{Price} {CurrencyCode}" />            <DisplayListItem                label="Supplier"                value="{SupplierName}"                type="Navigation"                press="handleSupplierPress" />        </List>        <VBox alignItems="Center">            <Image                src="{app>/ES1Root}{ProductPicUrl}"                decorative="true"                densityAware="false" />        </VBox>    </Page></core:View>

     

    We're not aggregating any array of data from the model here, we're just presenting four DisplayListItem controls one after the other in the List. Below that we have a centrally aligned image that shows the product picture.

     

     

    SupplierDetail View

     

    And finally we have the SupplierDetail view.

     

    <?xml version="1.0" encoding="UTF-8" ?><core:View controllerName="com.opensap.SupplierDetail" xmlns:core="sap.ui.core"    xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">    <Page        id="Supplier"        title="{CompanyName}"        showNavButton="true"        navButtonPress="handleNavButtonPress">        <List>            <DisplayListItem label="Company Name" value="{CompanyName}" />            <DisplayListItem label="Web Address" value="{WebAddress}" />            <DisplayListItem label="Phone Number" value="{PhoneNumber}" />        </List>    </Page></core:View>

    Again, nothing really special, or specially complicated, here. Just like the other views (apart from the "root" App view), this has a Page as its outermost control. Here again we have just simple, clean declarations of what should appear, control-wise.

     

     

    Conclusion

     

    So there you have it. For me, starting to write views in XML was a revelation. The structure and the definitions seem to more easily flow, so much so, in fact, that in a last-minute addition to the DemoJam lineup at the annual SAP UK & Ireland User Group Conference in Birmingham last week, I took part, and for my DemoJam session I stood up and build an SAP Fiori-like UI live on stage. Using XML views.

     

    This brings to an end the series that started out as an itch I wanted to scratch: To improve the quality of the SAPUI5 application code that was presented in the OpenSAP course "Introduction To Mobile Solution Development". There are now 6 posts in the series, including this one:

     

    Mobile Dev Course W3U3 Rewrite - Intro

    Mobile Dev Course W3U3 Rewrite - Index and Structure

    Mobile Dev Course W3U3 Rewrite - App and Login

    Mobile Dev Course W3U3 Rewrite - ProductList, ProductDetail and SupplierDetail

    Mobile Dev Course W3U3 Rewrite - XML Views - An Intro

    Mobile Dev Course W3U3 Rewrite - XML Views - An Analysis

     

    I hope you found it useful and interesting, and as always,

     

    Share and enjoy!

    dj

    Have you ever heard of AppBuilder?

    $
    0
    0

    Hi.

     

    A couple of day ago I posted a blog in SCNs mobile developer space to announce the release of AppBuilder.

     

    Since I hang around in the mobile developer corner all the time I totally forgot that the SAP UI5 community may also be very interested in this tool. Thanks to Shen Peng to make me aware of that.

     

    Available under https://tools.hana.ondemand.com/#sapui5 you can easily download, install and start coding SAP UI5 mobile based Apps.

    Just give it a try. Download, Unzip, Start (Limits apply).

     

    The nice thing about AppBuilder is that it is a IDE completely run in your browser. And which technology can render HTML5 best? Yes, current browser technology. So it is a natural decision to just edit the App you want to write directly in the technology you use to run the App.

     

    AppBuilder is a helpful tool to create Proof of Concept like Apps and the created code can easily be used as a starting point for your real project. Also it eases the access to OData services and works perfectly with SAP Mobile Platform Cloud Version (Trial available here: https://hanatrial.ondemand.com).

     

    And this is how it looks like:

     

    WYSIWYG Design view with drag & drop support:

    appbuilder_1.jpg

     

    Code View - for the serious developer:

     

    appbuilder_2.jpg

     

    Don't forget to share your experiences here.

     

    Have Fun,

    Martin

     

    Edit: Just forgot to point you to more resources for AppBuilder:

     

    SAP AppBuilder Developer Center

    Basic Patterns for Testable JavaScript Code

    $
    0
    0

    On the last GTAC Mark Trostler (a Google Software Engineer) has given a presentation about testable JavaScript Code and how testability relates to high quality code and adaptivity to requirement changes.You can apply these principles also to SAPUI5 development.  In the next weeks I am going to publish several blog posts around specific aspects of the testability of SAPUI5 applications. This video introduces some basics and I can really recommend watching the video:

     

    Mark Trostler(Google): "Testable JavaScript is a process. Whether starting with a blank slate or an already implemented application (or somewhere in-between) being able to test your JavaScript code simply, cleanly, and effectively is a necessary feature.

    While JavaScript is unique due to the myriad of environments within which it runs, there are several tried and true 'testable' methodologies from other languages which also hold true for JavaScript.And of course there remain the unique challenges that JavaScript developers must face while writing and testing their code. What patterns make code testable? Which anti-patterns hinder testing?What metrics and common sense guideposts can be used to measure the testability of our code? Once the process of creating testable code has started now what?

    Join me to break down the process of writing testable JavaScript. We will investigate ideas, patterns, and methodologies that greatly increase the testability, and hence the maintainability, correctness, and longevity of your code. Whether you write client- or server-side JavaScript mastering this process will greatly enhance the quality of your code."


    Video: http://www.youtube.com/watch?v=JjqKQ8ezwKQ&list=SPSIUOFhnxEiCODb8XQB-RUQ0RGNZ2yW7d

    Slides: https://docs.google.com/presentation/d/1dp0GOtvl2-pZoxkyzvGvq5zmPdMIDQIBzr2Vv_3JzQo/pub?start=false&loop=false&delayms=3000#slide=id.gd2fff574_080

    Viewing all 789 articles
    Browse latest View live




    Latest Images