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

UI5 Choropleth Map Control with Live Examples - Part 2

$
0
0

This is a continuation on blog post: SAPUI5 ChoroplethMap Control in which I introduced a reusable UI5 control for a map. So if you haven’t read that yet, I suggest doing so before reading any further.

map_mobile.png

 

My goal with the ChoroplethMap control is to provide a reusable, mobile-ready and easy-to-use UI5 control (see image above) that handles common use-cases for choropleth maps. In the last post we already got the choropleth map to show and bind it to a model. Now let’s add some more features to make it really usable.

 

New features and their descriptions are:

Properties height and width of the control can be defined.

 

Live example

smallmap.png

"width" : {type : "sap.ui.core.CSSSize", defaultValue : "100%"},
"height" : {type : "sap.ui.core.CSSSize", defaultValue : "400px"},
// Usage
var map = new js.ChoroplethMap({..."height": "400px", "width": "400px"});

Pretty self-explanatory what width and height mean.

 

Property stylefunction for custom styling of features.

 

Live example

custom_stylefunction.png

"styleFunction": {type : "any"},
function styleFunc(feature) {                                   return {                      fillColor: '#2ca25f',                      weight: 2,                      opacity: 1,                      color: 'white',                      dashArray: '3',                      fillOpacity: 0.9                    };                               }

Stylefunction is a callback function who should take a leaflet feature as input and should return an object that contains the style properties.

 

Events for click, mouseover and mouseout on map features

 

Live example

custom_events.png

 

events: {        "mapmouseover": {},        "mapmouseout": {},        "mapclick": {}      }
// Usage
map.attachMapclick(function(evt) {     var feature = evt.mParameters.target.feature;     ...
})

These are custom UI5 events that you can attach handlers to. They wrap leaflet events so you have access to the map layer and feature etc. Refer to leaflet examples for mode info see leaflet documentation.

 

Properties centerLat, centerLng and zoom.

 

"centerLat": {type: "float", defaultValue: "0"},        "centerLng": {type: "float", defaultValue: "0"},        "zoom": {type: "int", defaultValue: "2"}
// usage
var map = new js.ChoroplethMap({..."centerLat": 48, "centerLng": 18, "zoom": 4, });

You can use these to set the initial extent of the map or change the extent later.

 

Properties and setters for enabling or disabling dragging and zooming.

 

Live example

nodragzoom.png

"draggable": {type: "boolean", defaultValue: true},
"zoomable": {type: "boolean", defaultValue: true},
// usage
var map = new js.ChoroplethMap({..."draggable": false, "zoomable": false});

These are useful in case you have data for a defined area and want visualize it on a static map. Use disabling dragging and zooming combined with centerLat, centerLng and zoom.

 

 

Not all the properties have their setters implemented so if map does not reflect changes made, call to invalidate() might be needed.

 

Again you can find code with examples at:

https://github.com/kjokinen/ui5choroplethmap

 

Feel free to comment or suggest fixes/features.


jQuery Ajax Callback not called? Be aware with the context

$
0
0

This blogs explains a particular case when a jQuery Ajax callback might not be get called once the request is completed/succeed/failed. In this case, the callback is not found due to incorrect definition of a javascript context. In other words, the request is done but your controller does not respond to it.


 

I decided to create this blog after a little headache I had until 5 minutes ago but which started last week.

 

Use jQuery.ajax to call a service

 

If you are starting to deep dive in SAPUI5/OpenUI5/Hana development/jQuery/Ajax/Javascript like me, there is a good change of you having asked such question:

 

"How do I call a service on a server from SAPUI5? For example, a XSJS of my Hana server"


Asking the right questions lead to finding the right answers. I had this doubt recently and after reading some documentation, checking GitHub repositories, reviewing openSAP courses and watching some Thomas Jung's videos.... I realized that jQuery could solve this problem with its "ajax" function. Like the snippet below:

 

// (...)
var l_url = "/my/package/project/services/do_stuff.xsjs"; // Some back end guru coded some server side javacript here        jQuery.ajax(        {            url: l_url,            data:                {                    first_name: sap.ui.getCore().byId("txf_first").getValue(),                    last_name: sap.ui.getCore().byId("txf_last").getValue()                },            type: "POST",        }
// (...)

 

Handling Ajax response with jQuery

 

After succeeding on answering your first doubt, the next one follows:

 

"How can I handle server's response with Ajax?"

 

It's easy to see that jQuery's documentation specifies some parameters where you can include your own callback functions as below.

 

// (...)
var l_url = "/my/package/project/services/do_stuff.xsjs"; // Some back end guru coded some server side javacript here        jQuery.ajax(        {            url: l_url,            error: function(){                console.log("OMG! This would never happen according to the functional consultant!");            },            success: function(){                console.log("Holy moly! It works!");            },            data:                {                    first_name: sap.ui.getCore().byId("txf_first").getValue(),                    last_name: sap.ui.getCore().byId("txf_last").getValue()                },            type: "POST",        }
// (...)

 

Life is happy. You can handle anything you want from now on. However, maybe you have some big/complex handling logic which shouldn't be included directly inside a anonymous function of an ajax call. Maybe it's a good idea to have a specify function inside your MVC controller for that. For example, as shown below.

 

sap.ui.controller("registration.main", {
/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf currencyregistration.main
*/    onInit: function() {    },
/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf currencyregistration.main
*/
//    onBeforeRendering: function() {
//
//    },
/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf currencyregistration.main
*/
//    onAfterRendering: function() {
//
//    },
/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf currencyregistration.main
*/
//    onExit: function() {
//
//    }    onPressRegister: function(){        var l_url = "/my/package/project/services/do_stuff.xsjs";        jQuery.ajax(        {            url: l_url,            error: this.onRequestError,            success: this.onRequestSuccess,            data:                {                    first_name: sap.ui.getCore().byId("txf_first").getValue(),                    last_name: sap.ui.getCore().byId("txf_last").getValue()                },            type: "POST",        });    },    onRequestError: function(){        console.log("OMG! This would never happen according to the functional consultant!");        // show message        // (...)        // create log        // (...)        // redirect page        // (...)    },    onRequestSuccess: function(){        console.log("Holy moly! It works!");        // bind control        // (...)        // Adjust layout        // (...)        // show message        // (...)    },
});

 

Now you have a cleaner code. Great!

 

 

Looking at the bigger picture

 

Note that in my example the ajax call is done inside a function called "onPressRegister". This was on purpose and this information is crucial to understand the problem I want to show.This function is triggered when a button from my view is pressed. The link between the "press" event and the controller function is done initially inside the view. More specifically, inside the Button constructor.

 

 

sap.ui.jsview("registration.main", {    /** Specifies the Controller belonging to this View.    * In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.    * @memberOf registration.main    */    getControllerName : function() {        return "registration.main";    },    /** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.    * Since the Controller is given to this method, its event handlers can be attached right away.    * @memberOf registration.main    */    createContent : function(oController) {        var layout = new sap.ui.commons.layout.VerticalLayout();        layout.addContent( new sap.ui.commons.Label({            labelFor: "txf_first",            text: "First Name",        }));        layout.addContent( new sap.ui.commons.TextField("txf_first",{            maxLength : 20,        }));        layout.addContent( new sap.ui.commons.Label({            labelFor: "txf_last",            text: "Last Name",        }));        layout.addContent( new sap.ui.commons.TextField("txf_last"),{            maxLength : 30,        });        layout.addContent( new sap.ui.commons.Button("btn_register", {            text: "Register",            press: oController.onPressRegister, // HERE!! When the button is pressed, this controller function is called        }))        return layout;    }
});

 

Remember when we replaced our anonymous callback functions with named controller functions? On that step, we broke our code. I really suggest you to give it a try creating a simple SAPUI5 application and creating a simple XSJS as below.

 

do_stuff.xsjs

var first = $.request.parameters.get("first_name");
var last = $.request.parameters.get("last_name");
if (first != last) {
$.response.status = $.net.http.OK;
$.response.setBody("OK");
} else {
$.response.status = $.net.http.NOT_ACCEPTABLE;
$.response.setBody("NOT OK");
}

 

Be aware with your JavaScript context

 

Why? You might ask. If you debug your SAPUI5 application with Firebug for example you will notice that "this.onRequestError" and "this.onRequestSuccess" are undefined inside controller function "onPressRegister". This looks crazy at first, second, third, Nth sight... but it is the truth.

 

You might have seen some controller logic where a function inside a controller calls another one using this.anotherFunction. You can definitely do that if the context on which the first function is called is the controller itself. As it happens with the "hook" functions onInit and onExit for example.

 

So where is the catch?

 

You might read jQuery documentation all day long. Unfortunately, you will be cold as I was for some time. There is nothing wrong with the Ajax call. The problem is with our attachment between the "press" event of the button and the controller function.

 

Let's go back to our button constructor.

 

layout.addContent( new sap.ui.commons.Button("btn_register", {    text: "Register",    press: oController.onPressRegister, // When the button is pressed, this controller function is called
})

 

If you attach a controller function like this, it will be called using the button context and not the controller context. "press" is a button property which receives a function. That function might be a property from your controller. However, it doesn't mean that the context inside this function is the controller. Actually, it will be the button by default. The same issue happens if you use the "attachPress" function without filling the "oListener" parameter. Let's see how we can fix this.

 

First, we will not attach the controller method to the button event inside our view anymore.

 

 

layout.addContent( new sap.ui.commons.Button("btn_register", {    text: "Register",
//    press: oController.onPressRegister, // This link will be done inside the controller
})

 

We will make do this with our onInit function from the controller using the attachPress function aforementioned.

 

 

onInit: function() {    sap.ui.getCore().byId("btn_register").attachPress(null, this.onPressRegister, this); // The 3rd parameter means the context on which the function will be called.
// Here "this" means "this controller" and not "this button"
},

 

And this solves the "ajax problem". You could also use this method inside your view and passing the controller reference inside the last parameter as well.

 

Conclusion

 

So in the end of the day the problem was not jQuery neither Ajax. The problem was the javascript scope or context if you will. So, this situation could occur in any event which is not properly registered no matter if you are using ajax or not. I hope this post emphasizes the use of onInit to register listeners avoiding views to become root cause of controller issues.

 

This might sound too basic for some front end developers or maybe too specific but I'm sure that lots of people will get into this trouble on their first steps with jQuery/Ajax/SAPUI5/Javascript/MVC.

 

Do not forget to comment with your thoughts!

 

Fábio Pagoti

JavaScript based Integration Tests for SAPUI5 apps with OPA

$
0
0

Several colleagues asked me what I think about Selenium. Selenium has, similar to many tools, advantages and disadvantages and any advice can only be given context specific. 

Jonathan Benn has compiled the following list of good reasons for using selenium for testing in an internal blog:

  • Selenium is an excellent library for UI testing. It's succinct, easy to use, well-thought-out and reliable.
  • Assuming that the UI is easily testable, meaning that every UI element has a unique ID, tests are easy to write and maintain, and are reliable.
  • When the UI is less testable, e.g. because UI elements have repeated IDs or IDs that change over time, Selenium still makes it possible to test. Development time increases, and reliability and maintainability decrease, but at least it's still possible to test.
  • Thanks to its simulation of user interaction, Selenium enables a complete top-to-bottom integration test of the app. After running a Selenium test on a feature, you can feel very confident that the feature works as prescribed and that users will not run into problems.
  • Similarly, Selenium offers a lot of support during refactoring, since it's easy to tell if you broke any part of the app while making changes.
  • If you stick to testing the major use-cases of the app, Selenium tests will not require a lot of maintenance and will provide very good value for money/time spent.

 

These are all valid reasons for using selenium, especially for end-to-end testing scenarios. However, the authors of How Google Tests Software state: “But overinvesting in end-to-end test automation often ties you to a product’s specific design and isn’t particularly useful until the entire product is built and in stable form. And it’s still browser testing. It’s slow, you need hooks in the API, and tests are pretty remote from the thing being tested.” [How Google Tests Software]. Furthermore we’ve observed that it’s rather inefficient if there are people that write only tests while others are doing the coding without eating their own dog food. Therefore we thought about an alternative, avoiding these disadvantages.

Testing apps with JavaScript based tools, on the other hand, has benefits and this brings OPA5 into play: OPA5 is an extension for SAPUI5 controls developed by Tobias Oetzel. It hides asynchronity and eases access to SAPUI5 elements. This makes OPA5 especially helpful for testing user interactions, integration with SAPUI5, navigation, and data binding:

The OPA5 library is JavaScript based, meaning that you can write your tests in the same language in which your app is written. This has the following advantages:

  • Quick and easy access to JavaScript functions
  • Easy ramp-up as it can be used with any JavaScript unit test framework (e.g. QUnit, Jasmine)
    • For Jasmine the adapter is currently missing. If interested you can contribute on the GitHub project. The implemetation should be straightforward.
  • Using the same runtime enables debugging
  • Good SAPUI5 integration
  • Feedback within seconds makes it possible to execute tests directly after a change
  • Asynchronity is handled with polling instead of timeouts, which makes it faster
  • Enables test-driven development (TDD)
  • Easy TestDouble Usage: Can be combined with MockServer to isolate from the backend. This is also the recommended way to test your app, to avoid fragile test data and fragile backend systems.

 

Developer writes tests along with developing the app, thus ensuring from the beginning that the app is testable. This is important from a testability point of view, whereas having people writing tests while others do the coding without writing automatic tests is rather inefficient. TDD results in less fragile tests, because the app is better isolated and supports less fragile APIs for testing.

  • Follows the arrange act assert pattern (corresponds to given when then), which improves readability and understanding of the test cases
  • Easy to run on mobile devices, no plugins/apps are needed but you can just run it in the browser.
  • Saves time for the developer since regressions decrease

 

It is very easy to write acceptance tests with OPA5 – Give it a try! It is already used by many developers inside of SAP.




What you currently should not or cannot do with OPA5:

  • Screen capturing
  • Logging console errors
    • Missing feature
  • Testing across more apps
  • Remote test execution

 

How Google Tests Software, James Whittaker, Jason Arbin, Jeff Carollo, 2014

The documentation visible outside of SAP will be improve, so stay tuned. https://openui5beta.hana.ondemand.com/docs/guide/22f175e7084247bc896c15280af9d1dc.html

MockServer: https://help.sap.com/saphelp_uiaddon10/helpdata/en/41/5d1fc8cc154cb189809d3cb9747165/content.htm

 

Arrange Act Assert and Given When Then:

http://martinfowler.com/bliki/GivenWhenThen.html

http://xp123.com/articles/3a-arrange-act-assert/

Real-time notifications and workflow using ABAP Push Channels (websockets) Part 3: Creating a UI5 Application for receiving notifications

$
0
0

This is Part 3 of the below series of blogs:

 

 

Here we are going to create a simple UI5 Application which consumes the standard Gateway TASKPROCESSING service. This requires component IWPGW to be installed on the system and is the same service as is used by the Unified Inbox and Fiori Approve Requests. The application will display the users workflow inbox and will automatically notify them of new messages and refresh the list when a new work item is created via the workitem exit created in Part 2.

 

In Eclipse Using the UI5 Toolkit Create a new application.

 

Goto File->New->Other…

016.PNG

 

 

Select UI5 Application and press Next

017.PNG

 

 

Give the Project a name: ZWF_WF_INBOX_MINI

018.PNG

 

 

Give the view a name: Main and leave the Development Paradigm as Javascript and press Finish.

019.PNG

 

Expand the application created and paste the following code into Main.controller.js and Main.view.js

020.PNG


Main.view.js code:




sap.ui.jsview("zwf_inbox_mini.Main", {

 

      /**SpecifiestheControllerbelongingtothisView.

      *Inthecasethatitisnotimplemented,orthat"null"isreturned,thisViewdoesnothaveaController.

      *@memberOfzwf_inbox_mini.Main

      */

      getControllerName : function() {

            return"zwf_inbox_mini.Main";

      },

 

      /**IsinitiallycalledonceaftertheControllerhasbeeninstantiated.ItistheplacewheretheUIisconstructed.

      *SincetheControllerisgiventothismethod,itseventhandlerscanbeattachedrightaway.

      *@memberOfzwf_inbox_mini.Main

      */

      createContent : function(oController) {

            //Create List

            varoList = new sap.m.List();

   

            //Create ListItem Template

            varoListItem =

   

            //Bind list to collection

            oList.bindItems("/TaskCollection",

                                    new sap.m.StandardListItem({title : "{CreatedByName}", description : "{TaskTitle}"}),

                                    new sap.ui.model.Sorter ("CreatedOn", true));

   

            returnnew sap.m.Page("idPage1",{

                  title: "Worklist",

                  content: [ oList

                  ]

            });

      }

});

 

 

Main.controller.js code:



sap.ui.controller("zwf_inbox_mini.Main", {

 

/**

*CalledwhenacontrollerisinstantiatedanditsViewcontrols(ifavailable)arealreadycreated.

*CanbeusedtomodifytheViewbeforeitisdisplayed,tobindeventhandlersanddootherone-timeinitialization.

*@memberOfzwf_inbox_mini.Main

*/

      onInit: function() {

            //Initialise the websocket connection

            this.initWorkflowNotifyWebsocket();

   

            //Initialise OData Model using SAP standard TASK PROCESSING service from component IWPGW

            oModel = new sap.ui.model.odata.ODataModel("/sap/opu/odata/IWPGW/TASKPROCESSING;v=2");

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

   

            //Get Work item count

            this.setWorkitemsCount();

      },

 

      // this function returns the count of work items

      setWorkitemsCount: function(){

            // Get Tasks count

          $.get( sap.ui.getCore().getModel().sServiceUrl +"/TaskCollection/$count" , function(data) {      

            sap.ui.getCore().byId("idPage1").setTitle("Worklist (" + data + ")");

              }, "text")  ; 

      },

 

      //this function initialises the websocket connection

      initWorkflowNotifyWebsocket : function() {

            var hostLocation = window.location, socket, socketHostURI, webSocketURI;

            if (hostLocation.protocol === "https:") {

                  socketHostURI = "wss:";

            } else {

                  socketHostURI = "ws:";

            }

            socketHostURI += "//" + hostLocation.host;

            webSocketURI = socketHostURI + '/sap/bc/apc/sap/zapc_wf_notify';

              

            try {

                  socket = new WebSocket(webSocketURI);

                  socket.onopen = function() { };

                  varthat = this;

         

                  //Create function for handling websocket messages

                  socket.onmessage = function(wfNotify) {

                        //When a message is received refresh the OData model

                        sap.ui.getCore().getModel().refresh(false, null, null);

               

                        //Re-calculate the workitem count

                        that.setWorkitemsCount();

               

                        //Create a popup toast message to notify the user

                        sap.m.MessageToast.show(wfNotify.data);  

                  };

                  socket.onclose = function() {

                  };

            } catch (exception) {

            }

      },

 

/**

*SimilartoonAfterRendering,butthishookisinvokedbeforethecontroller'sViewisre-rendered

*(NOTbeforethefirstrendering!onInit()isusedforthatone!).

*@memberOfzwf_inbox_mini.Main

*/

//    onBeforeRendering: function() {

//

//    },

 

/**

*CalledwhentheViewhasbeenrendered(soitsHTMLispartofthedocument).Post-renderingmanipulationsoftheHTMLcouldbedonehere.

*ThishookisthesameonethatSAPUI5controlsgetafterbeingrendered.

*@memberOfzwf_inbox_mini.Main

*/

//    onAfterRendering: function() {

//

//    },

 

/**

*CalledwhentheControllerisdestroyed.Usethisonetofreeresourcesandfinalizeactivities.

*@memberOfzwf_inbox_mini.Main

*/

//    onExit: function() {

//

//    }

 

});

 

 

 

Deploy the application on your ABAP server or wherever you choose to and run it.

021.PNG

 

 

Now open the window next to the SAP GUI and create a new parked journal, which will go to my inbox for approval. On saving the Parked Journal document, the notification is immediately displayed in my browser window and the list is automatically refreshed with the worklist count in the header increasing from 260 to 261.

 

Before save:

022.PNG

 

After save - Inbox updated with new document automatically and popup notification displayed:

023.PNG

 

If you would like to try create a similar application in Web Dynpro ABAP see: Real-time notifications and workflow using ABAP Push Channels (websockets)  Part 4: Creating a Web Dynpro ABAP Application for receiving notifications

My path to learning OpenUI5.....deeper down the rabbit hole and back again!

$
0
0

    a-DNAU9g.png First off, I apologize for the length of the blog, but hey, no good journey is short one....I mean, what would "Lord of the Rings" have been if it began with Frodo taking the ring from his home, walking into his village and melting the ring in the town's bonfire...done and DONE!...but not quite the same story. haha Sooooo......

 

     Many moons ago now ("many" in technology terms) when the SAPUI5 announcement was made, I like many others had the same reaction..."and the crowd goes mild"....er what?!?!"...I was a little excited, but as I had no immediate need for it and did not have any clients even looking at HANA, the Gateway or anything else, I just kinda thought "well, SAP has yet another new web development solution....let's see how it goes and then MAYBE I will get interested." Perhaps after all these years, I was finally jaded on new SAP development technologies/models. I had been through the original ITS, the *improved* ITS with "flow control", through BSP with CRM/SRM, toyed with WebDynpro JAVA (enough to know I hated NWDI and everything it took to get in place just to START to code), and had really been enjoying WebDynpro ABAP for a while now. I figured if anything, it would be a bit like any other MVC-based framework....and even like good old WebDynpro ABAP....coding up the "views", their iterations, etc. should be fairly straightforward with the "real work" being as always, coding business rules/logic and interacting with data correctly on the backend.....been there, done that a bazillion time.... just another language/model/syntax/etc to learn to do it....so I kinda kept "interested from a distance". But then in December 2013, SAP announced OpenUI5...open source and free!!!  It felt like a big "Merry Christmas" gift from SAP to us. Better still, it was not just for SAP. I could work with it for "other" things! THAT got me interested!

 

     I guess maybe it would help to describe my background first though if I am going to talk about how I "learned" OpenUI5. If others were to follow, I would want them to understand the foundation/background I came from before getting into this. First off, I am NOT a "unique snowflake". Nothing unique about my background or anyone else who has done any kind of web development over the years. I have coded HTML and CSS through all their iterations, and of course most recently, HTML5 CSS3. Along with that, I have a experience in the usual related web dev technologies (JavaScript, JSON, AJAX, PHP) as well as some not-so-popular ones by comparison (classic ASP/ ASP.NET web forms and MVC) ...even written a few of my own C# web services from time to time (haha) . I had occasionally used JQuery (Lightbox plugin for example) where things were easier with it but for the most part steered clear from "JavaScript frameworks" just as much as CSS pre-compilers like LESS (think of it as programmable stylesheets). I always considered myself more of a "hand coder" and did not like to rely on others except where absolutely necessary and/or to not "reinvent the wheel". Along with my "hand code everything" stubbornness, I had watched so many "JavaScript frameworks" rise and fall over the years...so many seemed to come into fashion and then disappear just as quickly. I had just been waiting to see how the "dust would settle". Now, however, with SAP jumping into the fray, I thought it was my turn as well. Time to get to gettin' ...as they say (haha)...

 

 

Jumping right in....oh! This water is DEEP!

help-hand-stick-out-water-11408459.jpgI started looking for OpenUI5 info around early 2014. I wanted to find code examples, tutorials, the usual.....but found nothing really there. I found the runtime and SDK links....github page but no forks....what gives?

 

I started kind of studying SDK....a bit confusing.....where to start? Install is an "install"? What kind of web server? Where to put it local? Any good CDN?

 

Then I found DJ Adams' blog and furthermore his "OSCON" tutorial.... OpenUI5 Tutorial at OSCON 2014 | DJ's Weblog

 

Like most how-tos, it began with the familiar "step 1"....set up Node.JS.....but what is Node.JS?.....I found this (The Node Beginner Book » A comprehensive Node.js tutorial) The Node Beginner Book » A comprehensive Node.js tutorial and went through it...even spent the $9 to get the whole thing....thought of it as a little "tip" and "thank you" for his hard work and nice write up....learned lots from that tutorial....also checked out some other Node.JS tutorials/books but didn't spend too much more time on it (this blog is referenced in the OSCON material as well and is REALLY good too =>UI5 SDK on Node.js )...I got the main point of it by now (think of it as a web server without being a web server...allows you to run server side Javascript without a server...allows some awesome non-blocking, asynchronous wizardry...but you can do soooo much more with it too!)...Node.js did get me off track further a bit by looking at the Google V8 JavaScript engine....which then got me looking at Mozilla's "Rhino" JavaScript engine and then I stopped reading the Wiki's about the various engines. (haha)

 

Back to DJ's tutorial....went through the whole thing....it was GREAT! I got really excited by what I saw and how easy it was to build. I do not want to sound like a "brown noser", but I gotta say that DJ and the team did a VERY good job on this tutorial....it covers everything quite well with well explained, easy to follow steps. Kudos, DJ! The light-bulbs finally went on!...but I wanted to do more...dive deeper into OpenUI5....I had kicked the tires...I wanted to open this baby up and see what she could really do out on the open road! (haha)

 

Before I got ahead of myself, I had to jump over to something else that was bugging me now...like my sidetrack "learning" Node.JS....this brought more questions.....OpenUI5 seems great....but how does it compare to other "frameworks"....I recalled BLAG mentioning a few and I had played around with JQuery a time or 2 myself....if I wanted to really understand OpenUI5, I figured I needed to really try to understand its strengths and weaknesses compared to others as well as how and where it really shines the most. If you look for "Javascript Frameworks", you will find quite a lot...and I wasn't about to go through each and every one!

 

Comparison of JavaScript frameworks - Wikipedia, the free encyclopedia

 

So I stuck with the few that seemed most prevalent today.... AngularJS, JQuery, and Backbone.js and Agility.js (only because one of the Backbones sites claimed it was "a simpler alternative to Backbone.js." haha).

 

the Library vs Framework conundrum

As I was going through some AngularJS tutorials, I happened upon this very interesting page....

 

http://bitworking.org/news/2014/05/zero_framework_manifesto

 

JavaScript_Tools_Library_Frameworks.jpgLike many, I often (inadvertently) used "library" and "framework" interchangeably myself. That rant against JavaScript frameworks had me really thinking...especially the point he made about "snippets/Gist < Library < Framework". So I "pressed pause" on my self-teaching and wanted to better check this out. I had often seen mention of the "SAPUI5 framework" in early blurbs about it, but then, checking out the OpenUI5 page, it describes itself as "OpenUI5 is an Open Source JavaScript UI library". Looking around, it seems that for SAPUI5/OpenUI5, many people would switch the terms. But what about others? Looking up JQuery, it is listed as a "cross-platform JavaScript library", however if you look elsewhere, people call it a "framework" as well. I saw a question on Stack Overflow about what to really call it. One funny quote/response caught my attention, "One person's library is another person's framework." (haha). But another response put it well as "A framework is something that usually forces a certain way of implementing a solution, whereas [a libary] is just a [set of tools/controls/functions] to make implementing what you want to do easier." Ok....I got that....but I also got that a LOT of other people seem confused on the differentiation, so I felt better knowing I was not alone. (haha)

 

It only gets muddier when you consider things like this..."Generally a framework implies a [special] execution context while a library is just some external API that is used. However, by this definition then a jQuery Plugin would use the jQuery framework " (stackoverflow.com)....so even a defined "library" can actually be a "framework" depending on how you look at it.


In the end, I just figured "Ok....it is what it is." and went back to learning. I even found another great quote to support this...."Don't worry about it. Worry about what the particular library or framework can do to help you."That says itALL! (haha)

 

about-javascript-libraries-2-638.jpg

Back to it with reckless abandon! (ie. I don't care if it is a library, framework, toolset, etc....I just want to build something!!!)

To cut to the chase....here are the sites (aside from the official ones) that I studed/used/followed/read in order to learn the "basics" about each option. I am in no way saying these are the "only" ones or even the best ones to learn from, but they were the ones I found most immediately that helped me out..

 

Comparison of frameworks

Best JavaScript MVC Frameworks 2013-2014 | JonathanMH

 

JQuery (started here just to brush up on my JQuery since most all other "frameworks" have some manner....soft or hard...of dependence on it)

  HTML5, CSS3, and jQuery with Adobe Dreamweaver CS5.5 Learn by Video: David Powers (EXCELLENT ALL AROUND for HTML5, CSS3 and JQuery!)

  jQuery Hotshot eBook: Dan Wellman

  jQuery For Dummies: Lynn Beighley


Backbone.js (many places refer to it as the most "popular"..."most involved community"...etc...so I thought it best to start with)

     Backbone.js Tutorials

     Backbone.js  (the famous "TO DO" list and examples)

     Developing Backbone.js Applications  (awesome OPEN SOURCE version of the O'Reilly book!)

     Backbone.js Is Not An MVC Framework! (this was an interesting read!)

     (and I found that if doing anything with Backbone in addition to Underscore.JS and JQuery, you will often find mentioned Require.jsand Marionette.js to do even more with Backbone)

Agility.js (actually found this one through a Backbone.js tutorial site...since it was "easy"....another one to check out haha)

    Agility.js Javascript MVC library  (meh...I found it pretty simple...kind of a dumbed down version of Backbone)


AngularJS (since it is now backed by Google and seems to be gaining in popularity, I thought it was a good one to get familiar with.)

AngularJS Fundamentals In 60-ish Minutes - YouTube

AngularJS Tutorial &amp;#8211; Learn AngularJS in 30 minutes | RevillWeb

Introduction to Angular.js in 50 Examples (part 1) - YouTube  (Part 1 and 2 are VERY good! Steps you through everything nicely!)

http://code.tutsplus.com/tutorials/building-a-web-app-from-scratch-in-angularjs--net-32944  (really fun and good one...but only after learning basics!)

https://docs.angularjs.org/tutorial (this is Angular's own tutorial....once I felt a bit more comfortable with "what" Angular was, I dove into this one....and it was fun!)

http://www.artandlogic.com/blog/2013/05/ive-been-doing-it-wrong-part-1-of-3/ (really good 3 part series! can apply elsewhere too!)

AngularJS Lessons - Screencast Video Tutorials @eggheadio  (lots of good tutorial videos!)\

AngularJS for jQuery Developers

angular-app · GitHub (full blown, real world AngularJS built app....good to learn from just like looking at SAP code to learn ABAP! haha)

https://builtwith.angularjs.org/ (good collection of actual AngularJS apps...good to learn from and spark ideas!)

Backbonejs vs Angularjs : Demystifying the myths | Next Big Thing (good read!)


Others I looked at, browsed over, but really did not spend too much time on....

Knockout.js

Ember.js

Meteor (described as one of the few "top to bottom" frameworks where others are considered "front end"....might have to dive deeper into this one later haha)

Bootstrap (aka. Twitter Bootstrap) probably the most similar to OpenUI5 actually and documentation is nice! (haha)

 

...and again, I often would reference back to Blag's blog and look at the book reviews he had done since he is a fellow SAP Mentor/Geek/Gearhead/Friend and I trust his opinions:


Blag's bag of rants: Getting Started with PhantomJS - Book Review

Blag's bag of rants: MeteorJS and SAP HANA

Blag's bag of rants: Mastering Web Application Development with AngularJS - Book Review

Blag's bag of rants: Instant AngularJS Starter - Book Review

Blag's bag of rants: Learning jQuery, Third Edition - Book Review


web site vs. web app?mobile-app-versus-mobile-website-639x273.jpg

Like the "gray area" I discovered with JavaScript "frameworks" vs. "libraries", I soon found myself pondering the same thing around "web stuff" in going through all the above examples, tutorials and such. Like I said, web development is not new to me, but I never really thought that much of what "it" was that I created. I always just said "web stuff" if someone asked. I was always just coding web pages (or code that would create said pages in respect to scripting). Some just displayed content. Some were interactive. I might code up specific pages or groups of pages as a full web site. If my pages "did something", I might even interchangeably refer to them as a "web site" or "web application" and not think much of it. But there is really something different between a "web site" and a "web app" isn't there? How is a "single web page" different from a "single page web app"....or are they? Well, once again, I was not alone in this debate....


http://www.visionmobile.com/blog/2013/07/web-sites-vs-web-apps-what-the-experts-think/


After reading through that article (as well as others), I came to the understanding (as many others did) that there is really not a cut-and-dry difference of the two....and more often than not, we actually see a blended version of both. I think the whole "site" vs "app" debate is more often being largely fueled by marketing types to spice it up the sound of their solution and create this false impression of "site = old/dated" and "app = cool/new". In the end, I do not think that the difference in sites vs apps is technical at this point. In my opinion, it is simply an evolution in the user interaction experience that has come about due to the popularity and growth of "non-desktop" access. Users' expectations have just changed. Developing anything with a slant/focus on "web site" vs "web app" is about as pointless as developing a "desktop only" or "mobile only" solution in most cases. We have grown past that...users have grown past that.


However, one thing I read did strike me.....could I build a full blown web site with any of the MVC frameworks I looked at earlier? Sure.....but it would be so overblown and likely a nightmare to maintain. When faced with developing a "web solution" for a given requirement, I will focus more on "best tool(s) for the job" rather than "what to call it".


Back on track...full speed ahead!

So after spending time going through each of those, doing non-SAP examples, etc., I was all ready to jump back into OpenUI5 with reckless abandon now that I understood better it's place in the (web development) world.


First off was getting things set up. What web server to use? Well, since like I said, I do a fair bit of (dot)Net development, I already had IIS going. I also had Node.JS as an option now (and a cool one it is!!!). But I also found another DJ Adams' document ( Getting Started with SAPUI5: Alternative Guide ) that walks you through setting up a nice Apache web server for your use!  Next up...where was I going to develop my code? Which IDE to use? Well, again, I already had Visual Studio (the "express" version is free if you want to use it). I also had Eclipse. Both seemed a bit much for my simple web apps though. I had seen Sublime Text used in many videos and tutorials for many of the things I went through to this point, so I figured I would give it a try (and LOVE it! more on that later...). Last of course...Which libraries to grab and where to put them? Well, the latter is just a matter of personal taste and there are opinions on where is best. I actually wish SAP had a nice CDN, so I wouldn't have to bother with "grabbing" or "locating". Anyways, I downloaded the "latest and greatest" OpenUI5 SDK (and runtime for grins) from the official GitHub location, OpenUI5 - Download . I started off with the 1.20.10 version but over the course of this, I ended with the 1.22.8 version. So now, I was all ready to go!


And wouldn't you know it...lucky me....just as I was jumping back to it, I found NEW (new to me at least) documentation for the "mobile" library....WITH CODE EXAMPLES!!!! YEA!!!!! It can be found here: OpenUI5 Explored Not to mention, the Facebook SAP Developer group (SAP Developer Center | Facebook) start posting up some more info!

 

Before long though, I realized that I had this unnerving feeling of stumbling around and not really "getting it". I felt in working through these tutorials and "starters", I was really just "copying" the steps without understanding really why I was doing this-and-that, knowing options I could add/change, and figuring out what all was going on behind it. Sure, I had working code and nifty OpenUI5 apps, but I really had no idea how or why they really worked. So, as I probably should have done from the start, I dove right into the SDK and began reading it from end-to-end (some parts 2 and 3 times even).  I worked through the "Create Your First SAPUI5 Application", then on to the "Create Your First Mobile SAPUI5 Application", and I thought I was steaming along. Then, I tackled the "Application Best Practices" example and things came to a slow grind. Not only did it get complicated quickly, but the steps were rather confusing. Add to this that the code has bugs, and I was ready to pull my hair out (or just go back to ignoring OpenUI5 haha). I will save all the details, but will say that I got it working thanks to some helpful forum posts I found as well as things I had to figure out myself. These include:

 

  1. change the OData service call in your Component.js file from serviceUrl : "/uilib-sample/proxy/http/services.odata.org/V2/(S(sapuidemotdg))/OData/OData.svc/" to serviceUrl : "http://services.odata.org/V2/(S(sapuidemotdg))/OData/OData.svc/"
  2. this will lead you to another problem....a CORS error (ie. No 'Access-Control-Allow-Origin' header is present) in Chrome. To correct this on my Windows machine, I had to make sure all Chrome browsers are closed and run the command line "Chrome.exe --disable-web-security http://localhost/<path to your TDG example location>/index.html". You can look it up for your own system.


So I got through that and got back to reading the SDK. It was about then that I found all the other MUCH SIMPLER examples that are in the SDK (look under the "test-resources/sap/" directory...especially in the "demokit" directories under the branches for "ui" and "m"). These should keep you busy for a long while like they did me. (haha)


After going through the SDK, I was feeling a LOT better about my comfort level with OpenUI5, but I wanted to put myself to the test. I decided to go back through DJ Adams' (and team) great OSCON tutorial mentioned (and linked!) above and try to do it all on my own...as well as in other ways (ie. HTML views). Now THAT was an interesting "self assessment"! (haha)


...And then, something amazing happened......time had crept up on me, and it was that time again....time to go to SAP TechED (&& d-code now!) in Vegas...time to sit in on all kinds of SAP/OpenUI5 lectures, hands-on workshops, expert meet-and-greets, etc....and not to mention finding out how all of this ties into River IDE (now renamed "SAP Web IDE") and Fiori. Perfect timing!!!!


     Sadly, this is where our journey comes to an end...for now. I am by no means an OpenUI5 expert now, but I do think I went from "noob" to "slightly dangerous" level. (haha) Now, that I am learning more and more, be warned.....more and more OpenUI5 related blogs WILL follow! (haha)


freebonus-orange.png



BONUS BITS!!! : Other Helpful Bits Discovered Along the Way

Going through most of the tutorials, examples, etc. with the other "frameworks" as well as OpenUI5, I found a few tools,links,"things" (technical term),etc. here and there that I thought might be useful to others as well.



Sublime Text

I used Eclipse as well as Visual Studio 2010 Ultimate, but I also finally fiddled around with Sublime Text (version 2) because I had heard so much about it as well as many examples used it. I did find it very easy to set up, personalize and get working how I wanted. It really did make life a bit easier....at least for the more basic work I was doing (ie. no need for integrated testing tools and packagers....thought it does have packages for things like that too!) These links really helped me out to get it up and going:


Sublime Text - Download

Code checking and formatting in Sublime Text

qmacro/SublimeUI5 · GitHub


OpenUI5 for Visual Studio

And, since my prior experience in the .Net/Visual Studio world, I found this blog and walk through example for developing SAPUI5 in Visual Studio to be interesting.... Getting started with SAPUI5 and another one too SAP UI 5 aka Open UI 5 application development with Visual Studio. Both were fairly straightforward. The first was more geared to SAPUI5 and was fairly old (2012?). I read through it but not much else as much has changed since then. The second one was pretty basic (more just to show how to include the SAPUI5/OpenUI5 "resources" into a Visual Studio project).


GitHub

And since OpenUI5 is OPEN SOURCE (as is most everything else I delved into), I had to get up to speed on GitHub. If you don't know what it is (like me before this journey....I just thought "oh its like a code sharing thing"), well, there are plenty of sites (including GitHub) that will step you through it all. However, this was a really good "talk" about GitHub that really made me have a deeper understanding (as well as think of ways to apply these ideas elsewhere).....

http://yow.eventer.com/yow-2012-1012/how-github-works-by-zach-holman-1285

 

Miscellaneous (other useful nuggets found along the way)

Postman - REST Client (VERY cool REST client for CHROME!)

RESTClient, (cool Firefox add-on much like Postman)

JSHint, a JavaScript Code Quality Tool (Pretty sure folks know this one but it is a very good JS debugger...SublimeText2 has a package for it too!)


PLEASE feel free to add your own "cool tools and links" in the comments below as well!


Respect and Acknowledgement

I do want to end (and make sure) I give proper acknowledgement to those who really got me motivated and inspired to dive into OpenUI5. Oddly enough, they are all fellow SAP Mentors....but then, that makes perfect sense as one of the qualities of any SAP Mentor is that they actively try to inspire, teach and motivate others. Without their many posts, blogs, nudges, pushes, etc., I don't know if I would have finally thrown my hands in the air and exclaimed "ok! OK! Enough already!!!...I give up..I will learn OpenUI5!!!!" (haha). Soooo many thanks and respect to the following for the "push" into that deep water...

DJ Adams

Alvaro Tejada Galindo (aka. BLAG)

Graham Robinson

Chris Paine

Check Out the SAP Fiori UX Design Challenge: Winners Now Will Get an iPad Air 2

$
0
0

FioriandopenSAP3.pngWhat does the latest Apple news have to do with SAP Fiori and SAPUI5? Read on to learn more.

 

For the past month or so, openSAP has been running a free online course called Introduction to SAP Fiori UX and is trying something new: an optional design challenge open to anyone interested (participation in the main course is not required). It is called the SAP Fiori UX Design challenge, and here's how it works:

 

There are two short videos (available via the course page) which specifically cover the topic of SAP Fiori UX Design. You'll learn how and why SAP Fiori was created in the first place and then also be given some guidance on how you can apply the same design approach SAP used internally to create a mockup of your own Fiori-like app.

 

You pick any SAP scenario you are interested in that involves SAP transactions (for example, scenarios involving submitting, managing, or viewing approvals, leave requests, or sales orders), and then submit your own idea showing how you think SAP Fiori UX could make this scenario a more delightful and simple experience.

 

No previous design experience is required and anyone can participate. Your submission is really about telling a short story in whatever format and style works best for you. You'll also have access to additional resources, such as the SAP Fiori Design Best Practices Guide (taken from the SAP Fiori Design rapid-deployment solution) and the SAP Fiori UX Prototyping Kit.

 

All entries must be submitted by Monday, October 20, and although participation in the main Introduction to SAP Fiori UX course itself could be helpful, it is not required. Meaning, anyone can get started even today, watch these two short videos, and submit an entry by the deadline next week.

 

And the top three submissions will each win a free iPad Air. Scratch that, after Apple's announcement today, we've decided, why not make it a brand new iPad Air 2? So the top three submissions will each win a free iPad Air 2!

 

For more details, check out the challenge introduction page (requires free openSAP account) as well as the FAQ. As always, feel free to ask questions or comment below. We know many of you have seen a user interface and thought, “I could design something much better than that.” And now's your chance to show the world your skills. We are looking forward to seeing what you come up with.

 

Best of luck!

 

(Standard disclaimer: If Apple runs out of iPad Air 2's after selling however many bazillions in the next couple weeks, there may be a delay in winners receiving their new iPad Air 2. But we'll work to get winners their iPad Air 2's soon after said winners are determined.)

End to End scenario of SAPUI5

$
0
0

Hi,

The motto of this Post is to give start to expert level information about SAPUI5.

Which will Cover

  1. What is OpenUI5/SAPUI5
  2. Basic installation detail
  3. Creating First SAPUI5 App
  4. Concepts of SAPUI5
  5. Best Practices
  6. Designing Fiori like app using SAPUI5
  7. Netweaver Gateway services
  8. Consuming OData in SAPUI5 Application

 

Let's begin:

  1. What is OpenUI5/SAPUI5:

SAPUI5 is an extensible JavaScript-based HTML5 browser rendering library for Business Applications.
Ÿ

        Supports RIA like client-side features based on JavaScript

  • ŸSupports an extensibility concept regarding custom controls
  • Allows change of themes for customer branding in an effective manner
  • ŸAllows usage of own JavaScript and HTML
  • ŸUses the jQuery library as a foundation
  • ŸFully supports SAP Product standards
  • ŸOpen AJAX compliant and can be used together with/uses other standard JS libs
  • ŸCan be used from various platforms (Java, ABAP, etc)
  • ŸProduced in a release independent code line to enable short shipment cycles

Note:

For anyone who has not heard of OpenUI5 / SAPUI5 before can follow the link

Posted by Andreas Kunz

What is OpenUI5 / SAPUI5 ?

  

2.  Basic installation detail:

          Follow below link it will give you step by step installation detail

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

 

3.Creating First SAPUI5 App:

Upto now your eclipse is ready to go..

so create a simple application  SAPUI5 SDK - Demo Kit

Very easy way...so you can see a nice App.

 

4.Concepts of SAPUI5

Some of the core concept behind SAPUI5 are

  • UI5 architecture overview
  • Model View Controller (MVC)
  • Data Binding
  • Routing
  • Resource Handling
  • SAPUI5 Component
  • Fragments
  • Styling and Theming
  • Extending SAPUI5
  • Optimzing UI5

In my next Blog i'll cover Concept of SAPUI5.

Thanks and regards,

Rajesh Roy

End to End scenario of SAPUI5

$
0
0

Hi Guys,

This blog is extension of my previous blog End to End scenario of SAPUI5 .

In this blog we'll go through Concepts of SAPUI5.

Core concept behind SAPUI5 are

  • UI5 architecture overview
  • Model View Controller (MVC)
  • Data Binding

Let's go one by one...

UI5 architecture overview

architecture_overview (1).png

when we create an SAPUI5 app we need to provide runtime environment to our app which we do by including bootstrap  with a <script> tag in index page.

 

<script id="sap-ui-bootstrap"

  type="text/javascript"

  src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"

  data-sap-ui-theme="sap_goldreflection"

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

Which initiate the core.

UI5 pages always have to start with the bootstrap, to initializes the UI5 runtime.

Attributes of the script tag are evaluated and used to configure the runtime

  • Ÿdata-sap-ui-libs:the controls libraries to be used, comma-separated
  • Ÿdata-sap-ui-theme:the theme
  • ŸThere are moreattributes: data-sap-ui-language, data-sap-ui-rtl etc.
  • ŸInstead of putting the attributes in the script tag, they can also be added as URL parameters.

UI5 Core

  • UI5 Core includes base, core and model modules
  • Dependency / Class-Loader to load control libraries
  • Render manager creates HTML strings for the instantiated controls
  • The UI5 Core includes other JavaScript libraries

          jQuery

          jQuery UI

         data.js

Some Useful Core functions :

sap.ui.getCore()

  • Ÿget a core instance

sap.ui.getCore().byId(id)

  • Ÿgets an instance of a UI5 control which was created with id id
  • Ÿcan be used to retrieve removed controls (even though the id doesn’t exist in the DOM anymore)

sap.ui.getCore().applyChanges()

  • Ÿcarries out and renders the changes for UI5 controls directly, so before the runtime would do it

jQuery.sap.domById(id)

  • Ÿgets any HTML element with id id
  • ŸIf there is also a UI5 control with id id, the element returned is the topmost HTML element of this UI5 control
  • ŸThe topmost HTML element of a UI5 control always has the id defined for the UI5 control

jQuery.sap.byId(id)

  • Ÿreturns the jQuery object of the DOM element with the specified id
  • Ÿsimilar to document.getElementByIdthe name of id

UI5 control libraries


sap.ui.commons

  • ŸIncludes “bread and butter" controls like TextField, TextView, Button, Link etc.

sap.ui.ux3


  • ŸIncludes UX3 patterns, mainly available in “Gold Reflection” design

         Ÿe.g.: ShellExActand Thing Inspector


sap.ui.table

  • ŸIncludes DataTable

Note: To know about more Controls provided in SAPUI5 visit link SAPUI5 SDK - Demo Kit


Model View Controller (MVC)

In the Model View Controller concept, the representation of information is separated from the

user's interaction:

 

• The view is responsible for defining and rendering the UI.(SAPUI5 SDK - Demo Kit )

 

• The model manages the application data. ( SAPUI5 SDK - Demo Kit )

 

• The controller reacts to view events and user interaction by modifying the view and model.

 

MVC provide following advantages:

 

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

 

Views and controllers often form a 1:1 relationship, but it is also possible to have controllers without a UI, these controllers are called application controllers.

For further detail please refer SAPUI5 SDK - Demo Kit .

 

Data Binding

In UI5, data binding is used to bind UI5 controls to a data source that holds the application data, so that the controls are updated automatically whenever the application data is changed.

 

The model instance holds the data and provides methods to set the data or to retrieve data from a server. It also provides a method for creating bindings to the data. When this method is called, a data binding instance is created, which contains the binding information and provides an event, which is fired whenever the bound data is changed.

 

Binding Modes:

 

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

 

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

 

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


SAPUI5 data binding supports three different model implementations.

JSON model

  • Ÿsupports data in a JavaScript Object Notation format
  • Ÿsupports two way binding

XML model

  • supports XML data
  • supports two way binding

OData model

  • supports ODatacompliant data
  • creates OData requests and handles OData responses
  • includes the open source library dataJS to handle OData requests and data

Steps to data binding:

• Create a model instance.

• Create a control instance.

• Bind properties or lists of the control to your model.

eg:

Creating a Data Binding Model Instance

// create JSON model instance

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

// set the data for the model

oModel.setData(data);

// set the model to the core

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

OR

Assigning the Model to the UI

Procedure

Choose one of the following options:

• You can define a global model that can be accessed by all controls from all UI areas by

using the setModel method on the SAPUI5 core object. This is useful for simple form

applications or demo applications.

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

• You can also define a specific model for sections within a UI area, for example, inside a

panel or for a table control. In this case, you can use the setModel method available on

any control:

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

oTable.setModel(oModel);

for further detail follow link SAPUI5 SDK - Demo Kit

for real time example follow link sapui5 beta - databinding .


SAPUI5 applications – is SAP Gateway always necessary?

$
0
0

In a lot of blogs and presentations SAP Gateway is mentioned as the communication layer between the SAPUI5 application and a SAP backend system. One of the main advantages of SAP Gateway is that the communication is handled with the ODATA protocol. This protocol is amongst other responsible for the navigation between entities in a service (like a sales order and its positions) and handles part of the security of the communication.

pic1.png

Is SAP Gateway always necessary? See for example the following scenarios:

 

  • A company does not have a SAP Gateway system available and/or the current SAP backend system has to be upgraded in order to communicate with SAP Gateway;

 

  • The requested application contains only a simple overview without any navigation;

 

  • The application will only be used within the own (company) network en there is no need to call the application from outside this network.

 

In the above scenarios the advantages of ODATA (and to some extent SAP Gateway) are not as clear as in other scenarios. Another possibility here is to use a direct communication between the application and the backend system with help of JSON.


SAPUI5 is perfectly capable of handling JSON formats (e.q. standard libraries available for JSON model) and a SAP Netweaver ABAP stack also has several tools for processing this format.

pic2.png

A SAPUI5 application can, as mentioned, use several models, like for example an ODATA and JSON model. This document presents a way to communicate with a SAP backend system without the use of SAP Gateway.

 

One of the possibilities to send a response to a SAPUI5 application in JSON format, is to create an own handler class which has to be linked to a (new) ICF node. This class will have to implement interface IF_HTTP_EXTENSION, which is needed for processing the request. This (new) ICF node will be directly linked under the ‘DEFAULT_HOST’ node, which shortens/simplifies the navigation path from outside the system. The handler class can determine what kind of request has to be done. Dependent of the type of request the data collection will be executed and the data will be returned in JSON format.

 

That’s all about the theory! Let’s have a look at an example and configure the system so the data will be displayed in a SAPUI5 application. The first step to be executed is the creation of a handler class with will process the request.

pic3.png

First determine in method HANDLE_REQUEST which type of request has to be executed (this is only needed when the ICF node is used for multiple types of requests).

 

pic4.png

 

Next step is to perform the data collection and after this step the retrieved data is transformed into a JSON string.

 

pic5.png

 

Finally the JSON string has to be added to the response (don’t forget to set the content type as well) and the status should be set to ‘successfully processed’.

pic6.png

The handler class is ready now, next step is to define an ICF node which will be the access point for the SAPUI5 application.

 

pic7.png

 

The handler class has to be attached to the node.

 

pic8.png

 

The backend configuration is completed now. Next step is to enable the SAPUI5 application to communicate with the created ICF node.

 

pic9.png

 

Create the connection between the fields in the internal table (in this case SO_ID) and the columns of the table in which the data will be presented.

 

pic10.png

The last step is to link the created model to the table and also indicate which node will be called in the JSON file.

 

pic11.png

 

See the results of all performed actions, where the content of the internal table is displayed in a SAPUI5 application.

 

pic12.png

 

When completing (or reading) the article, it hopefully becomes clear that converting an internal table into a JSON file with help of you own handler class, is an easy way to publish data into a SAPUI5 application. So in case of the scenarios earlier mentioned, this solution is a good alternative for using SAP Gateway.

 

 

Peter Boertien

peter.boertien@newitera.nl

www.newitera.nl

How to use Chrome Dev Toolkit for UI5 development

$
0
0

The chrome dev toolkit is a very simple to use and it can be used to debug , learn , explore and experiment with your UI5 code.

In this article will talk about following tabs of chrome console, few of the discussion are very obvious but it was not that obvious for me when i started using it:

  • Elements.
  • Network .
  • Source
  • Profiles.

To open Console press Fn + F12 / Ctl + shift + c

 

 

Elements:

 

This part of console will let you know about what is the HTML the browser is rendering :

 

You can use this to navigate to specific element in html and see its HTML rendered content :

 

element1.jpg

The other best use of it to change the CSS and see the change reflected on the fly in your page , you can also play with some of the standard CSS elements of UI5 and change its property and see what are the changes occurs in the web Page , but be aware that there are many places where the CSS properties are used so , changing them here would also change the content everywhere the class is used.


Network:


This is very important tab if you are having AJAX GET and POST request with your application you can use this tab to see the header status , response(content you get) and timing(to see the sequence of the operations):


network.jpg

Source:

(Console and emulation)

This is one of the most used tab by me in the development , you can pretty much see all the files which are used in the UI5 Application in the File browser:

 

 

source1.jpg

The one more exciting this you can also do some development in the JS file and it is just like a smart Editor :

source2.jpg

and if you did some changes and save it then sometimes you no need to refresh the application to check how the changes are , when the changes are some actions where the control is to be passed then the new changes will be executed

 

 

source3.jpg

 

The console of the toolkit is one of the sweetest , it is a playground sometime to tryout entire logic to see it it will work and then do the development :

 

example if you want to have a new panel and add it to old then:

 

 

source4.jpg

the most cool thing about the panel if you do not know what are the methods you can use for oldPanel then you can get it's object and you will get list of the possible operations and functions:

source5.jpg

 

you can also see the definition of a function if you will only mention its name without calling it i.e without '()' appended at its end.

And if you want to explore the objects of then just open it in the console and go as much level down as your curiosity will take you it is amazing way to explore the inheritance of UI5 as well:

 

navigation.jpg

 

Emulation tab in will help you to see how your application will look like in the specific device:

 

 

 

source7.jpg

 

 

Profiles

 

The first thing in the Profile is you can see CPU Profiles for  JavaScript function run time and idle duration in tree manner and also get % , sometimes if there is an operation we are worried about is having the performance glitch and we can not find it in network part of the kit then this will probably give some clues.

profiles1.jpg

 

 

The other very cool thing you can do here is see heap snapshot , the two most important thing in a execution is heap and stack the stack stores the program execution and heap is storing the dynamic memory allocation of runtime .

When you are dealing with huge size of data or huge number of data in an analytic appliaiton then it is pretty handy one.

 

heap.jpg

and stack:

stack.jpg

 

 

 

 

Cheers

 

-Regards

Ajay Nayak

UI5 language translation search behavior using Resource classes

$
0
0

I have an application shows German translations for some of the phrases, and English translations for other phrases.

However, if the browser language is English, every phrases show the English translations. This happens in IE browser.


It took me some time to figure out the puzzle as the cause of the issue is not obvious. Hope this blog will save you some time.

 

Usually, for accessing localized text, you provide property files with language code at the end of file names, for example: i18n_en.properties for English translations. Then you use Resource class to access the localized texts. For example:

 

var gLocale = sap.ui.getCore().getConfiguration().getLanguage();

var i18n = jQuery.sap.resources({

  url : "i18n/i18n.properties",

  locale : gLocale

});

sap.m.MessageToast.show(i18n.getText("ENTER_POSI_NUM"));

 

When the Resource class searching the translation based on UI5 derived browser language code, for example, de-DE(for German (Germany)), if the corresponding i18n_de-DE.properties doesn't exists, it will fetch the translation from i18n_de.properties file if it exists. It is special feature of the Resource class.

 

However, if you want to use the Formatter to display the translated phrase, the Formatter class don't have this feature. You have to set the language code specifically or add some logic to handle the scenario.

 

For example you phrase translation json data structure is like below.

      "name":{

            "de":"Diverses",

            "en":"Miscellaneous"

         }

You want to use a formatter to show the translation based on language code, the formatter function will need to make sure to cover the scenario such as de-DE.

For example,

 

getI18nName : function(name){

  var i18nName = "";

  var mainLangCode = gLocale.substring(0, 2);

  if(name != undefined){

  if(name[gLocale] != undefined&& name[gLocale].length > 0){

  i18nName = name[gLocale];

  }elseif(name[mainLangCode] != undefined&& name[mainLangCode].length > 0){

  i18nName = name[mainLangCode];

  }else{

  i18nName = name["en"];

  }

  }

  return i18nName;

  }

 

Now, even the UI5 derived browser language code is de-CH (for German (Switzerland)), you will have a catch all German translation for it.

 

Then in the view, you can use:

<core:Itemtext="{ path:'name', formatter:'util.UiDataFormatUtil.getI18nName'}"key="{id}" />

 

Thanks!

 

Siyu

UI5 JSONModel Fuzzy Search

$
0
0

Introduction


In this blog post I’ll introduce a fuzzy search utility that searches a JSONModel for items matching input text. Fuzzy search or approximate string matching is used to find matching items or text strings when search input does not exactly match any item or part of an item. A really good example of a fuzzy search in use is Google Search’s auto correcting suggestions.

 

Fuzzy search measures the closeness of search input with the items and then returns best matching items. Closeness can also be called edit distance. Closeness is calculated by counting the number of primitive operations, such as swapping a character with another, needed to convert the search input into an exact match.

 

Example:

fuzzysearch.png

 

Implementation


Implementation is done by wrapping JavaScript library Fuse.js. Fuse is a lightweight client-side fuzzy-search. in JavaScript. It is meant to be used with small to medium data sets.

 

As fuzzy search utility is client-side, it is not implemented to work with ODataModels as they may not have all the data available on the client. OData fuzzy search should be implemented on the server.

 

Usage


Fuzzysearch’s constructor takes three parameters:

 

  • JSONModel

JSONModel that contains the array to be searched.

 

  • path

Path of the array in the JSONModel.

 

  • options

Options to be used with Fuse. Refer to Fuse documentation for all possible options.

 

 

Fuzzysearch provides one method: search that is called with a search text string. The method returns an array of best matching item indexes that are sorted by items’ closeness to the search string.

 

Example with fuzzy search for countries of Europe similar to examples at sap.ui.commons.SearchField:

 

var aCountriesOfEurope = ["Bulgaria", "Croatia", "Cyprus", "Czech Republic", "Denmark", "Estonia", "Finland", "France",                          "Germany", "Greece", "Hungary", "Iceland", "Albania", "Andorra", "Austria", "Belarus", "Belgium",                          "Bosnia and Herzegovina", "Ireland", "Italy", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg",                          "Macedonia", "Malta", "Moldova", "Monaco", "Netherlands", "Norway", "Poland", "Portugal", "Romania",                          "Russia", "San Marino", "Serbia and Montenegro", "Slovakia (Slovak Republic)", "Slovenia", "Spain",                          "Sweden", "Switzerland", "Turkey", "Ukraine", "United Kingdom", "Vatican City"];
aCountriesOfEurope.sort();
var countryJson = {"countries": aCountriesOfEurope};
var countryModel = new sap.ui.model.json.JSONModel(countryJson);
var options = {
 threshold: 0.4
}
var fuzzySearch = util.fuzzysearch(countryModel, "/countries", options);
var results = fuzzySearch.search(“genma”);

closenesssearchresults.png

 

Live example

 

Code link

 

Thanks for reading.

SAPUI5 applications – is SAP Gateway always necessary?

$
0
0

In a lot of blogs and presentations SAP Gateway is mentioned as the communication layer between the SAPUI5 application and a SAP backend system. One of the main advantages of SAP Gateway is that the communication is handled with the ODATA protocol. This protocol is amongst other responsible for the navigation between entities in a service (like a sales order and its positions) and handles part of the security of the communication.

pic1.png

Is SAP Gateway always necessary? See for example the following scenarios:

 

  • A company does not have a SAP Gateway system available and/or the current SAP backend system has to be upgraded in order to communicate with SAP Gateway;

 

  • The requested application contains only a simple overview without any navigation;

 

  • The application will only be used within the own (company) network en there is no need to call the application from outside this network.

 

In the above scenarios the advantages of ODATA (and to some extent SAP Gateway) are not as clear as in other scenarios. Another possibility here is to use a direct communication between the application and the backend system with help of JSON.


SAPUI5 is perfectly capable of handling JSON formats (e.q. standard libraries available for JSON model) and a SAP Netweaver ABAP stack also has several tools for processing this format.

pic2.png

A SAPUI5 application can, as mentioned, use several models, like for example an ODATA and JSON model. This document presents a way to communicate with a SAP backend system without the use of SAP Gateway.

 

One of the possibilities to send a response to a SAPUI5 application in JSON format, is to create an own handler class which has to be linked to a (new) ICF node. This class will have to implement interface IF_HTTP_EXTENSION, which is needed for processing the request. This (new) ICF node will be directly linked under the ‘DEFAULT_HOST’ node, which shortens/simplifies the navigation path from outside the system. The handler class can determine what kind of request has to be done. Dependent of the type of request the data collection will be executed and the data will be returned in JSON format.

 

That’s all about the theory! Let’s have a look at an example and configure the system so the data will be displayed in a SAPUI5 application. The first step to be executed is the creation of a handler class with will process the request.

pic3.png

First determine in method HANDLE_REQUEST which type of request has to be executed (this is only needed when the ICF node is used for multiple types of requests).

 

pic4.png

 

Next step is to perform the data collection and after this step the retrieved data is transformed into a JSON string.

 

pic5.png

 

Finally the JSON string has to be added to the response (don’t forget to set the content type as well) and the status should be set to ‘successfully processed’.

pic6.png

The handler class is ready now, next step is to define an ICF node which will be the access point for the SAPUI5 application.

 

pic7.png

 

The handler class has to be attached to the node.

 

pic8.png

 

The backend configuration is completed now. Next step is to enable the SAPUI5 application to communicate with the created ICF node.

 

pic9.png

 

Create the connection between the fields in the internal table (in this case SO_ID) and the columns of the table in which the data will be presented.

 

pic10.png

The last step is to link the created model to the table and also indicate which node will be called in the JSON file.

 

pic11.png

 

See the results of all performed actions, where the content of the internal table is displayed in a SAPUI5 application.

 

pic12.png

 

When completing (or reading) the article, it hopefully becomes clear that converting an internal table into a JSON file with help of you own handler class, is an easy way to publish data into a SAPUI5 application. So in case of the scenarios earlier mentioned, this solution is a good alternative for using SAP Gateway.

Use GitHub Pages to host your OpenUI5 app!

$
0
0

If you want to learn OpenUI5 but has no place to deploy your app (like inside a Hana system, SAP Gateway or any paid hosting service) this blog was made specially for you. If you have a place to host your app but also want another free and public alternative read this as well. I will show you what you need to do to host a OpenUI5 app using GitHub Pages, a free service provided by GitHub.

 


 

Following the SAPUI5 Momentum described by Graham Robinson, there are many skills which should be learned in order to work with SAPUI5/OpenUI5. Personally I'm doing my best to improve skills like Javascript, jQuery, node.js, etc to become more than an ABAP developer should be nowadays. One of such desirable skills is Git, which enables you to version your source code in a very clever way. When you talk about Git, it's hard not to mention GitHub, which enables you to share your projects (aka repositories) publicly or privately to your team (the last it's a paid service).

 

 

GitHub Pages

 

Probably you already know Git and GitHub and probably you have some public repositories which prove how a good and versatile developer you are. If you don't, you definitely should.

 

But maybe you are not familiar with GitHub Pages yet. And even if you have heard about them... maybe you just didn't realize that you can use them in order to deploy/host your apps created using OpenUI5!

 

github_pages.jpg

 

Why GitHub Pages?

 

It's very cool to share your development projects publicly and GitHub makes that possible on an effective way. Your repositories can be downloaded, cloned, forked and pushed by others.

 

However, there are many repositories which have some (or lots of) prerequisites that must be completed so the person trying to use your code can be successful. For small dependencies like tiny and open libraries, you can obviously share the dependent files collectively within your own repository. When the dependency is big or complex enough, the smartest decision is to document all required setup inside your repository wiki, another feature provided by GitHub.

 

GitHub Pages address another frequent requirement from developers: the need of a website for their repositories, usually nothing really complex... just a hotsite. GitHub Pages is a free hosting service provided by GitHub on which you can host static content like HTML, CSS and Javascript files. With GitHub Pages, you can advertise your repository for those are not developers and who don't even know GitHub.

 

If you have ever visited a website with an URL with the substring "github.io" you already visited a website hosted using GitHub Pages. You might not know, but the official OpenUI5 website is delivered using GitHub Pages.

 

http://sap.github.io/openui5/

 

Alternatively, you can use the URL below, as GitHub Pages support custom domains:

 

http://openui5.org/

 

Isn't that cool?!

 

 

Why GitHub Pages to host OpenUI5 apps?

 

Now you know how GitHub Pages can help you... but let's leverage our creativity now. Imagine you are studying or working with OpenUI5 and you are using GitHub repositories to share your work so others can benefit from it.

 

Wouldn't be better to demonstrate the power of your repository before the user try to download it and setup their environments? Isn't better to let another developer or a user to test/use your application online and decide if it is worth a clone?

 

You guessed right! Of course you can use GitHub Pages to host your OpenUI5 apps. OpenUI5 apps are made of static files.

 

 

Creating GitHub Pages

 

First of all, you will need a GitHub account. If you don't have it create it now... it's free and you can have as many public repositories as you want.

 

 

Personal/Organization Pages

 

The very first type of page you can create is for your own GitHub user. If you want to create a hotsite linking all your cool projects like I'm planning to do in my new GitHub Page, I recommend using such alternative. This type of page is simply a special GitHub repository following a simple name convention.

 

My GitHub username is "fabiopagoti", so in order to create a GitHub Page for my account, I had to create a new repository named "fabiopagoti.github.io" (it must be username.github.io otherwise it won't work).

 

After that you can create a normal web app inside this repository and push it to GitHub. The very first time you push content to this repository, it will take some time in order to have your page available. GitHub website says it should take up to 10 minutes but in my case it took 30 minutes. If you want to spend your time during this period with something useful, you might want to watch OpenUI5 presentation at OSCON on YouTube.

 

If you use organizations inside GitHub, you can definitely create pages for them as well. Just follow the same convention (organization.github.io). SAP's page on GitHub is actually an organization page.

 


Repositories Pages

 

As aforementioned, you can also create pages for a specific repository. Assuming you already have a repository, using such alternative there is no need to create another one (like you need for setting up personal/organization pages). In fact, repositories pages are created and delivered using a special remote branch called gh-pages.

 

The easiest way of creating this remote branch is inside your repository settings. There you will find a button called "Automatic Page Generator". Then, you just need to follow the 2 steps wizard.

 

At the right side, click on "Settings".

Captura de Tela 2014-10-28 às 18.24.18.JPG

 

Next, create some content for your initial GitHub page. Notice that you can also insert a Google Analytics tracking ID so you can keep track of the traffic to your GitHub Page. Awesome!

Captura de Tela 2014-10-28 às 18.24.41.JPG

 

Finally, choose a template from the options. You can change it later if you want.

Captura de Tela 2014-10-28 às 18.25.24.JPG

In the end, you have a complete hotsite for your repository. Remember that for repository pages it is delivered as a branch name.

 

To switch between your actual repository and its pages use the button as show in the images below.

Captura de Tela 2014-10-28 às 18.25.47.JPG

 

git hub pages open ui5.JPG

 

Hosting your OpenUI5 app

 

Now what you need to do to host your OpenUI5 app using GitHub pages is simply pull the content generated from the wizard (inside gh-pages branch for repository pages and master branch for personal/organization pages). Then, add the files from your app, commit them and push the changes to the gh-pages remote branch.

 

Personally, I like the templates generated from GitHub Pages and I wouldn't replace them with my OpenUI5 app completely (but of course you can create the whole page for your app using OpenUI5. Instead, I would simply create a new folder inside your branch and add your app there as I did below.

 

 

Captura de Tela 2014-10-28 às 20.22.41.JPG

 

More information

 

To know more about GitHub Pages, read the official documentation of GitHub Pages Basics.

 

 

Examples inside this blog

 

In order to learn OpenUI5, I'm creating a couple of applications which consume some public RESTful APIs from New York Times. I consider them a great example of a well-defined, documented and free web APIs. To know more about such apps, follow me at GitHub.

 

 

Share your GitHub page!

 

So... what are you waiting for? Share your GitHub page in the comments of this blog and share push your thoughts!

How to: temporary PDF creation and download

$
0
0

     This blog post describes how to create a PDF document based on input from the UI5 front-end and return a (temporary) download link to the user. It is mostly a collection of things I discovered whilst handling a task which involved exactly this king of thing.

 

1. Building the .pdf


     There are several ways to build the pdf itself. The easiest that I could find was using smartforms (you can find more details on how to create and use smartforms in the link). One thing to note is that the smart form has an interface similar with that of  a function module, i.e. you can pass data (values, structures, tables, basically anything) to it in order to fill the placeholders, generate tables, etc. Once you have created your  "template" using the smartforms feature you should create a function module / static method which uses this smart form, converts it into pdf format (because smart forms are not directly translated into .pdf files when executed) and saves it on the application server.


  • Getting the raw (otf) format output of the smart-form:

 

 

  DATA:

    ls_job_output_info      TYPE ssfcrescl,

    ls_document_output_info TYPE ssfcrespd,

    ls_job_output_options   TYPE ssfcresop,

    ls_output_options       TYPE ssfcompop,

    ls_control_parameters   TYPE ssfctrlop,

    lv_fm_name              TYPE rs38l_fnam.

 

 

  CONSTANTS c_formname TYPE tdsfname VALUE'<<smart form name>>'.

  CONSTANTS c_filename TYPE string VALUE'<<filename>>.pdf'.

 

  CALLFUNCTION'SSF_GET_DEVICE_TYPE'

    EXPORTING

      i_language   = sy-langu

      i_application = 'SAPDEFAULT'

    IMPORTING

      e_devtype    = ls_output_options-tdprinter.

 

  ls_control_parameters-no_dialog = 'X'.

  ls_control_parameters-getotf = 'X'.

 

  CALLFUNCTION'SSF_FUNCTION_MODULE_NAME'

    EXPORTING

      formname = c_formname

    IMPORTING

      fm_name = lv_fm_name.

 

  CALLFUNCTION lv_fm_name

    EXPORTING

      control_parameters  = ls_control_parameters

      output_options      = ls_output_options

      "add your custom smart form parameters here

    IMPORTING

      document_output_info = ls_document_output_info

      job_output_info     = ls_job_output_info

      job_output_options  = ls_job_output_options.

 

 

 

  • Converting the otf to pdf format:

 

 

  DATA: lt_lines           TYPESTANDARDTABLEOF tline,

        lv_pdf_content     TYPE                   xstring.

 

  CALLFUNCTION'CONVERT_OTF'

    EXPORTING

      format  = 'PDF'

    IMPORTING

      bin_file = lv_pdf_content

    TABLES

      otf     = ls_job_output_info-otfdata

      lines   = lt_lines

    EXCEPTIONS

      OTHERS  = 1.

 

 

 

  • You can either save the .pdf temporarily or you can persistently save the xstring value (returned in lv_pdf_content) in a database table and build a GW function import / entity which provides the binary content as a property. We will explore the first version. The first version has the advantage that it does not store large amounts of data in the database, although it will have to recreate the .pdf each time the user may want to download it (this is generally a good solution, as users mostly download receipts/confirmations/other pdf stuff just one time).

 

 

  DATA:   lr_cached_response TYPEREFTO            if_http_response,

          lv_header_text     TYPE                   string,

          lt_lines           TYPESTANDARDTABLEOF tline.

 

  CONSTANTS: c_path TYPE string VALUE`<<desired url local path>>` ,

             c_exp  TYPE i VALUE360."<<how long (secs) should the pdf be 'stored'>>

 

 

  CREATEOBJECT lr_cached_response TYPE cl_http_response EXPORTING add_c_msg = 1.

 

  lr_cached_response->set_header_field(

              name = if_http_header_fields=>content_type

              value = 'application/pdf').

 

***optional_start*** "should only be used if you wish to force a download

                     "(some browsers open .pdf files in tabs if you don't use it)

 

  CONCATENATE`attachment; filename="` c_filename `"` INTO lv_header_text.

 

  lr_cached_response->set_header_field(

              name = if_http_header_fields=>content_disposition

              value = lv_header_text ).

 

***optional_end***

 

  lr_cached_response->set_status(code = 200 reason = 'OK').

  lr_cached_response->server_cache_expire_rel( expires_rel = c_exp ).

 

*you can get the server base url using: cl_http_server=>get_location( ).

*when you build your path.

 

  lr_cached_response->set_data( lv_pdf_content ).

  cl_http_server=>server_cache_upload( url     = c_path

                                       response = lr_cached_response

                                       scope   = ihttp_inv_global ).

 

  • You have your .pdf saved at the url given in c_path (you may want to replace this constant with a url created at run-time, e.g. with a guid appended to the server base url.

 

2. Using it in GW

    

     Let's link the pdf creation function module / static method to the gateway service. I suggest using a function import which receives parameters derived from the structure(s) used in the smart form interface and returns a complex type which contains the URL (and other metadata if necessary). If appropriate, you can also create an entity set or use an existing entity and pass the URL as a property.

     Gateway service 'nodes':

     Function import settings:


     After you generate the run-time artifacts, you must redefine the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~EXECUTE_ACTION of the _DPC_EXT class and call your PDF creation function module (after you have checked that your function import is requested and not some other one). More on function imports here.


3. Linking it to the UI


     The gateway function import must communicate with the UI5 app. To call the function import use the callFunction method of your oDataModel object. You must write a javascript function to handle the success event (check out the parameters of the above-mentioned function). The function should be something like this:


function(oData, response)
{      var pdfURL = oData['getPdfFile'].url;     //use the url however you want.
}


     You have multiple ways to display the PDF once you have the URL. One thing that I have done, is to check if the PDF file still exists before redirecting the user to download it (the PDF may have expired if the user took a long time between creating the PDF and trying to download it; if this is the case and he presses the download link, a 404 Not Found default file will be opened and the UI5 context will be destroyed). You can use the following snippet to check if the pdf exists:

jQuery.ajax({    type: 'HEAD',    url: pdfURL,    success: function() {            //this will make the browser download the pdf            window.location.href=pdfURL;      },     error: function(){ /* error handling */ }
});

   

     If you want to display the .pdf file, here are some thoughts (you must not include the optional part in the PDF creation code):

  • Directly open it using  window.location.href=pdfURL; but this will basically exit from your application
  • Use the window.open function to open a new tab / browser window
  • Open it in an iframe (you can include the iframe in a UI5 dialog, or any other UI5 container control):
new sap.ui.core.HTML( {content: "<iframe style=\"width:100%;height:100%\" src=\"" + pdfURL+ "\">Not supported</iframe>"} )
  • All the above methods assume that the browser can display PDF files. If your PDF is accessible via a public URL (not on intranet and not behind a login), you can also use the Google Documents API. You can combine this method with all of the above. To use the API, you just have to build this URL:
var googleURL = "http://docs.google.com/viewer?url=" + pdfURL + "&embedded=true"

          and use it instead of the regular PDF URL.


Monitor HTTP traffic on mobile device

$
0
0

When developing a SAPUI5 (or any other) mobile application, it could be handy to be able to see the HTTP requests the application triggers (debugging, performance, caching,...). I had this issue myself and after some googling and fiddling around (pun intended), I managed to monitor the HTTP traffic through Fiddler on a laptop. These are the steps I did to make it work.


  1. Install and configure Fiddler
  2. Set Fiddler as Proxy on your mobile device
  3. Install Fiddler certificate on mobile device
  4. Start monitoring your application!

 

1. install and configure Fiddler

 

Fiddler is a great, free tool to log your HTTP traffic. You can download it via http://www.telerik.com/fiddler . Download and install the executable and you’re good to go. There are also a number of interesting add-ons available for Fiddler but you don’t need them in this case.

 

Fiddler.jpg

 

Some tips:

  • Fiddler captures all HTTP traffic on your machine so the log can grow very fast. You can limit the HTTP calls Fiddler should log by using the ‘Any process’ button in the toolbar. Just drag-and-drop to a specific program (ie. Browser window) to limit the logging to the specific process.
  • If you don’t need logging at a specific time, click on the capturing button on the bottom left of the window to stop/start monitoring.

 

Next you’ll have to configure Fiddler to do 2 things:

  • Decrypt HTTPS traffic
  • Set Fiddler as a proxy for external connections

 

Naturally without specifically configuring HTTPS traffic should be decrypted, there wouldn’t be much to see about these requests. The first thing you’ll have to do is configure Fiddler to decrypt HTTPS traffic.

 

Go to ‘Tools’ – ‘Fiddler options’ – tab ‘HTTPS’ and select the checkbox ‘Decrypt HTTPS traffic’

 

https_decrypt.jpg

 

The moment you select this option, Fiddler will prompt you with a dialog to ask if you want to install a Fiddler generated root certificate.


trust_cert.jpg

 

Some short info about how Fiddler works to help you make the right decision: Fiddler basically acts as a web browser the moment it starts logging your HTTP traffic and sends the HTTP traffic through to the appropriate process. However when you want to capture and analyze HTTPS traffic, Fiddler will have to decrypt these requests (as a normal browser will do). When forwarding these requests, your browser will detect the traffic has been decrypted (and encrypted again) by Fiddler and will give you a security warning. Basically Fiddler performs a Man-In-The-Middle to analyze your traffic. To avoid this warning, Fiddler generates its own (not trusted) certificate and asks you if you want to install the certificate (pfew… finally we arrived at the dialog above)

 

If you select ‘Yes’ the Fiddler certificate will be installed on your local machine and you won’t receive these warnings again. If selecting ‘No’ the certificate won’t be installed, so you’ll have to accept it in every browser manually.

 

The second configuration you’ll have to do is allow Fiddler to act as a proxy to receive traffic from other processes. This can be done in the tab ‘Connections’ by checking ‘Act as system proxy on startup’ and ‘Allow remote computers to connect’. As long as you don’t have another process running on port 8888, you can leave this default.


remote_access.jpg


After restarting Fiddler, you are ready to start capturing traffic!


2. Set Fiddler as Proxy on your mobile device

 

Next you’ll need to configure the device to send its network traffic via Fiddler. This is done by configuring a manual proxy in your wireless settings. To see which are the settings of the proxy server, you can simply hover over the status icon/text on the top right op the Fiddler window and you’ll get a popover like this:

 

proxy_info.jpg

 

Below you’ll see the IP address of your proxy and the port will be 8888 (if you didn’t changed it). The IP address will probably be in the 192.168.x.x, 172.16.x.x or 10.x.x.x ranges. Make sure to connect to a network before configuring the proxy.

 

Android:

  • go to your Wi-Fi overview
  • long tab the active network
  • ‘modify network configuration’
  • checkbox ‘Show advanced options’
  • proxy hostname = <IP> & port = 8888

 

IOS:

  • ‘settings’
  • 'general'
  • 'Network'
  • 'Wi-Fi'
  • under 'HTTP Proxy' select manual
  • server = <IP>, port = 8888 and Authentication = OFF

 

Windows:

  • Go to your Wi-Fi overview
  • tab the connected network
  • you’ll see a proxy option with a switch turned off
  • after turning this switch on, enter server/URL = <IP> and port = 8888
  • don’t forget tapping 'done' when finished

 

3. Install Fiddler certificate on mobile device

 

At this point, you should be able to see the HTTP requests from your device appear in Fiddler, but the HTTPS requests will be grayed out… To check if your mobile device is correctly routed through Fiddler, go to your browser and enter ‘http://<ip>:8888’. You should get the Fiddler echo service, roughly looking like this:

 

Fiddler_echo.jpg

 

Here you have the option to download the Fiddler Root certificate (this is the same principle as explained when we enabled Fiddler to decrypt HTTPS). Click this link and install the certificate.

(Android asks to give the certificate a name. I would suggest giving it a clear name like ‘Fiddler Root’ and use it only for Wi-Fi.)

 

4. Start monitoring your application

 

All done! Now you should see the HTTP(S) requests from your mobile device being captured in Fiddler!


result.jpg

 

I hope you find this blog useful! Please let me know if certain steps are unclear, contain errors, typos,… or if you have ideas to make it better.

 

 

Happy debugging!

SAP UI5 Local DB

$
0
0

Hello ,

 

Have you ever faced below issues:

 

  • You are going to conduct an UX workshop organized for the client and you have to quickly make the prototypes to tell customer how the app will look like using SAP UI5 and you do not have enough time to create the required back end and middle ware component ready till the time so you stick with some JSON mockup data and you really felt the need more data and a better way to make this work.

 

  • You are designing a POC for a customer and backend and middle ware component takes too much time to develop and you just want the customer to see and get impressed with the UX and UIs of the new app they are going to get and using JSON mockup data in static files seems to be not the best choice.

 

If you have then there is a good news I can give you , there is a small attempt to create a local Database which can be perfect way to deal with the above challenges:

 

Local DB v01

 

is a small project just initiated which will allow you to make use of local storage as a local DB , local DB is tested in 2 application POC in chrome browser and it works like a charm .

 

The project is just started and there are many improvement to be done but you can use the version 1 here , document home is here and main usage document is here.

 

Any feedback and suggestion for improvement will be highly appreciated.

 

cheers

 

-Ajay

From Mobile First to SAPGUI HTML5 client with Neptune Application Designer 3.0

$
0
0

In the three years our company Neptune Software has existed a lot has happened in the world of HTML5. The prominent design philosophy of the time was “Mobile first” and the first iPad had been released a year before. Steve Jobs had paralyzed Flash and Silverlight for mobile - effectively crowning HTML5 as the de facto standard for RIA frameworks.

 

For SAP customers HTML5 support for browsers was limited due to the "Sorry, your browser/program is not supported by Web Dynpro!" message. Smartphones and tablets came out as major players in the consumer market and the rapid replacements of new devices assured HTML5 support way ahead of W3C.

 

So our product strategy of mobile first was a no-brainer at the time and we started out with jQuery Mobile and Phonegap as our first frameworks for the designer at the same time as John Moy wrote his first blogs on the subject. 

 

Now, three years later, we are releasing our 3.0 version (keeping our promise of a major release a year) with loads of new functionality. Since even the IE browsers of SAP customers are starting to get to an acceptable level of HTML5 support and SAPUI5 has matured to a premium framework for responsive design we are embracing enterprise desktop usage of HTML5 in a big way. 


Njål Stabell will cover the new application management features in another blog so I will focus on two specific features of the 3.0 release – The Neptune GUI Client and our new HTML5 enhanced application designer.


Our idea for using HTML5 in the SAP GUI is actually a few years old, but is was reignited by Maximilian Schaufler when he visited the inside track in Oslo and had some nifty SSO2 setup to prevent additional login and session handling for the user. As opposed to the Nordic countries we found that SAP customers in the DACH region rarely use portal or NWBC and the majority are primarily using the SAPGUI as client for their SAP systems.


Neptune GUI Client

 

1.png

 

The Neptune GUI Client is a configurable and customizable client where the menu is dynamically displayed for the end-user based on Roles in the SAP system. The same menu can also be used in Neptune created mobile hybrid apps giving the users the same functionality no matter which device they connect to their SAP system.


In some ways it can be viewed as an NWBC for the SAP GUI. You can add Neptune Applications, URL’s or even SAP Transactions as items in the Neptune Application Management transaction and limit the access by connecting them to policies based on your SAP roles

 

2.png

We have added branding functionality to the menu, so that the end customer can be aligned with the company’s design guidelines. Let’s face it - end-users are more loyal to their employers than their software vendors. You can easily change colors and logos for the menu.

 

3.png

Lastly we have added an easy to use translation tool to be aligned with the easy translation of apps in the general application designer

 

4.png

 

The enhanced Application Designer

5.png

 

For a long time we have been looking into adding a proper editor for HTML5, CSS and JavaScript inside the Application Designer and therefore the SAPGUI. Finally it is here and we think it looks great. You can of course change the theme in the settings if the sublime text look is too colorful for your taste.


The editor comes with Syntax check, autocomplete and also a UI5 helper with all properties and events for the SAPUI5 controls.


A big thanks to Mark Teichmann for assisting us with implementing this feature!

 

Syntax Check

6.png

 

Autocomplete

7.png

 

UI5 helper

8.png

 

JavaScript Snippets

9.png

 

Neptune created snippets for fast coding

10.png

CSS

11.png

 

 

HTML5

12.png

 

There are tons of more new features in our 3.0 release and you can find some in Njål Stabell 's upcoming Application Management blog but you should also check out our release notes for a list of all of them. Hopefully you will get the chance to test out the new features and remember that developer license are free.


We have planned our release date for 3.0 (November 10th) to be aligned with  SAP TechEd & d-code Berlin where we have a booth to show the new features and do some on-the-spot training if you are interested.

 

Ole-André Haugen

Odata Service SAPUI5 app on SAP HANA Cloud

$
0
0

I have been searching a lot for a concrete document which has the step of configuring a generic ODATA service on internet (here in our case it is

https://companylistdemo.hana.ondemand.com/refapp-companylist-web/companylist.svc/)

But have been able to get it in parts. So once I have implemented it successfully i wanted to put all those together.

 

So lets start.
Intially, when we have a SAPUI5
Project which uses a generic Odata service somewhat in this way:

 

 

model creation

  var oModel = new sap.ui.model.odata.ODataModel("proxy/https/companylistdemo.hana.ondemand.com/refapp-companylist-web/companylist.svc/", false);

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

 

Now If you push this app to your HANA cloud account it would throw an error for obvious reasons. So you have to set up things on the cloud in such a way
that the your application would be able to fetch data from the above mentioned odata service.

 

 

The Configuration to be done are:

 

Configurations

1. Creating  a destination to the odata service from SAP HANA Cloud.

2. Adding  a file called “neo-app.json” to your project so that the name of the destination gets mapped.

 

 

 

So firstly lets go to our SAP HANA Cloud account. Create a new application under HTML5 Applications .

chrome.jpg

 

 

Enter the Name of the application for example <apponcloud>. Now click on it and go to the Development Tab to pick the Git Repository Url for cloning the repository to the local system.

 

chrome.jpg

 

 

Open Eclipse go to the  “GIT Repositories” View and click on “Clone a Git Repository.” Paste the url copied a in dialog box which pops up. Also
give the credentials of the SAP HANA Cloud Account and finish.

 

chrome1.jpg

 

 

 

Now you would see the the application directory in GIT Repository View as shown above. Then right click on the repository<apponcloud> and “Import
Projects” then select the option “Import as general project” as shown below then give a name and finish.

 

chrome2.jpg

 

 

 

You would notice that in the “Project Explorer” a project named <apponcloud> appears.Till now we have only got the ground ready for our development.

Lets add a bit colour to our project. Right click on the project on the “Project Explorer” add a new file named “index.html”.

Now add the following code to index.html:

 

 

------------------------------------------------------------------------------------------------------------------------------

 

 

<!DOCTYPEHTML>

<html>

<head>

<metahttp-equiv="X-UA-Compatible" content="IE=edge"/>

<metahttp-equiv="Content-Type" content="text/html;charset=UTF-8"/>

<title>SAP HANA CLOUD</title>

<!--replace "server" and "port" with your local installation or use https://sapui5.hana.ondemand.com-->

 

<scriptsrc="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"

id="sap-ui-bootstrap"data-sap-ui-libs="sap.m"data-sap-ui-theme="sap_bluecrystal">

</script>

 

<!-- only load the mobile lib "sap.m" and the "sap_bluecrystal" theme -->

 

<script>

 

var oModel = new sap.ui.model.odata.ODataModel("proxy/https/companylistdemo.hana.ondemand.com/refapp-companylist-web/companylist.svc/",false);

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

 

 

 

  var app = new sap.m.App("myApp", {

 

             initialPage: "page1"

 

       });

 

 

       var oPage = new sap.m.Page("page1", {

 

             title: "Company List"

 

       });

 

 

       var oTable = new sap.m.Table({

 

 

             id: "Company",

             mode: sap.m.ListMode.None,

             columns: [

 

             new sap.m.Column({

 

 

                    width: "1em",

                    header: new sap.m.Label({

 

                           text: "ID"

 

                    })

 

 

             }),new sap.m.Column({

 

 

                    width: "1em",

                    header: new sap.m.Label({

 

                           text: "Company Id"

 

                    })

 

 

             }),new sap.m.Column({

 

 

                    width: "1em",

                      header: new sap.m.Label({

 

                           text: "First Name"

 

                    })

 

 

             }),new sap.m.Column({

 

 

                    width: "1em",

                      header: new sap.m.Label({

 

                           text: "Last Name"

 

                    })

 

 

             })

 

             ]

 

 

       });

 

 

       var template = new
sap.m.ColumnListItem({

 

 

             id: "first_template",

             type: "Navigation",

            visible: true,

             selected: true,

            cells: [ new sap.m.Label({

 

                    text: "{Id}"

 

             }),new sap.m.Label({

 

                    text: "{CompanyId}"

 

             }),new sap.m.Label({

 

                    text: "{FirstName}"

 

             }),new sap.m.Label({

                    text: "{LastName}"

 

             })

 

             ]

 

       });

 

       oTable.bindItems("/Employees", template);

       oPage.addContent(oTable);

         app.addPage(oPage);// add page to the App

       app.placeAt("content"); // place the App into the HTML document

 

 

</script>

   </head>

<bodyclass="sapUiBody">

       <divid="content"></div>

  </body>

</html>

 

-------------------------------------------------------------------------------------------------------------------

 

Had this file been tested locally the output would be something like this.

 

chrome3.jpg

 

 

 

Now push the changes in project to the cloud account. Create a version and activate it. Now test your app you would get the following error.

 

chrome4.jpg

 

This is where we should do our bit. As said previously we need to create a destination from our SAP HANA Cloud Account.

 

chrome5.jpg

 

 

 

 

Click on the Destinations tab and then click on “New Destination”. Fill in the given details.

 

Name= cloudbackend

Type= HTTP

URL= https://companylistdemo.hana.ondemand.com

ProxyType= Internet

CloudConnectorVersion= 2

Authentication= NoAuthentication

-------------------------------------------------------------

WebIDEEnabled= true

WebIDESystem= cloudbackend

WebIDEUsage= odata_gen

 

 

chrome6.jpg

 

 

Now our Second part. Lets go back to the project<apponcloud> in the Project Explorer of Eclipse and add an new file named “neo-app.json”.
Paste the following code in the neo-app.json file.

----------------------------------------------------------------

{


"welcomeFile": "index.html",


"routes": [

    {
"path": "/destinations/cloudbackend",

  
"target": {

     
"type": "destination",

    
"name": "cloudbackend"

 

      },
"description": " Company List"

    }

  ]

}

 

-------------------------------------------------------------------------------------------------------------------------

Now the last step in the “index.html” replace the following line

 

 

 

Old Code

  var oModel = new sap.ui.model.odata.ODataModel("proxy/https/companylistdemo.hana.ondemand.com/refapp-companylist-web/companylist.svc/", false);

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

 

 

with the new code.

 

New Code

var oModel = new sap.ui.model.odata.ODataModel("/destinations/cloudbackend/refapp-companylist-web/companylist.svc/", false);

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

 

 

Now for the last time push your changes to the cloud and activate the version.Thistime around the application on the cloud will be having a referenced destination as shown below.

 

 

chrome7.jpg

 

 

 

  Now if you test your Application url. Fortunately it would fetch the data from the oData service.

 

 

chrome8.jpg

 

Great!!!!!!

BI Launchpad Menu with sap.m.StandardTile

$
0
0

I want to create a simple tile-based menu which user can click the tile to go to the next level menu and eventually will get the detail page with the link and useful information on the report. I also add the search function to search on the particular tile/report. I am applying this for the BI portal menu. That was the objective of this blog.

Slide1.JPG

 

Firstly, we need to define the JSON structure to get and populate the information. I obtained the information from the table AGR_HIER and AGR_BUFFI and join them together to create the following structure and convert into a JSON format:

 

{

  "modelData": [

    {

      "PARENT_ID": "11",

      "OBJECT_ID": "2",

      "SORT_ORDER": "60",

      "ME": "2",

      "N": "F",

      "TCODE": "",

      "SAP_GUID": "",

      "TARGET_SYS": "",

      "TEXT": "Asset Accounting",

      "X_POS": "7585",

      "Y_POS": "2878",

      "INFOS": "",

      "URL_TYPE": "",

      "URL": "",

      "SOURCEROLE": ""

    }

]

}

 

A complete JSON data can be found in the GitHub.

 

Filtering Function

 

On this design, I have created four views based on the total number of levels from the biggest value in 'MENU_LEVEL-ME' in JSON data (i.e, 4). Let us keep this design simple at the moment for learning purpose.

 

For each levels, we will do a filtering based on the PARENT_ID to create the tiles from JSON model: modelData.

 

function createTilesFromModel( oTileContainer, modelPath, id) {

  if (oTileContainer.hasModel() == false) {

  console.log("Error:" + oTileContainer);

  return;

  }

  var filter =  new sap.ui.model.Filter("PARENT_ID", sap.ui.model.FilterOperator.EQ, id);

  var template = new sap.m.StandardTile({

  title: '{TEXT}',

  info: '{ME}',

  icon: 'sap-icon://task',

  activeIcon: 'task',

  customData : [{

  Type:"sap.ui.core.CustomData",

     key:"OBJECT_ID",

     value:"{OBJECT_ID}"

   }

  ],

  tooltip: "{URL}",

  press: function (evt) {

  var sO = evt.getSource().data("OBJECT_ID"); //Destination

  oController.onNavButtonTo(evt, sO);

  }

  });

 

  oTileContainer.bindAggregation("tiles", {

  path: modelPath, filters: filter, template: template

  });

 

 

 

  }

 

To continue to the next level, once user clicked on the tile, we pass the OBJECT_ID to the context in onNavButtonTo.

 

press: function (evt) {

  var sO = evt.getSource().data("OBJECT_ID");

  oController.onNavButtonTo(evt, sO);

  }

 

The OBJECT_ID will become a PARENT_ID in the subsequent views and call the createTilesFromModel function.

 

this.addEventDelegate({

  onBeforeShow: function(evt) {

createTilesFromModel(MyTileContainer, "/modelData", evt.data.context);

  }

  }, this);

 

And finally, the Detail view (last view) will show the report name and the URL.

 

oTableMat.bindAggregation("items", {

         path: "/detail",

         template: new sap.m.ColumnListItem({

             cells: [

                     new sap.m.Label({ text: "{dText}" }),

                     new sap.ui.commons.Link({

              text : "{dText}",

              href : "{dUrl}",

              target : "_blank",

              tooltip : "{dUrl}"

              })

             ]

         })

     });

 

this.addEventDelegate({

  onBeforeShow: function(evt) {

  this.setModel(sap.ui.getCore().getModel('detailmodel'));

  }

  }, this);

 

 

 

Thanks for reading my blog, do let me know if you have any comments/questions.

 

Source code:

https://github.com/ferrygun/SAPBIMenu

Viewing all 789 articles
Browse latest View live




Latest Images