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

Working With XML Views:Using Local styles & stylesheets

$
0
0
Introduction:

 

When thinking of custom applications in SAPUI5, the first thing strikes in mind is which kind of UI view that we are going to implement. Particularly in cases where there is tremendous CSS changes involves, people directly goes to Javascript views. The simple reason is adding CSS in JS views are easy for a beginner compare to XML views.

 

Purpose:

 

This blog intended to give as insight of using CSS styles in XML views.

 

Scenario:

 

1. Using external Style sheets in XML view
2. Using Local Style class in XML Views

 

Pre-requisite: Basic Knowledge in SAPUI5 using XML Views.


Implementations:


Scenario 1: Using external Style sheets in XML view-This is a case where tremendous Custom CSS needs to be added to the application.

              


Step1: Create a SAPUI5 application, choosing XML as view type. The result will have a XML view and controller as below

 

XML view1.PNG


Step2: Create a folder for CSS, under it create a .css file

xmlv view 2.PNG

 

Step 3:Go to index.html and include the external style sheet, created in step 2 as in below picture

xml view3.PNG

 

Step 4: Add styles classes to your .css file (created in step 2) and save it.

 

.header{

       display:block;

              width:340px;

              padding:15px;

              margin:15pxauto;

              background-color:rgba(63,166,149,1);

              box-shadow:2px3px3px0rgba(63,31,0,.5);

              border-radius:10px;

              text-align:center;

              text-decoration:none;

 

       }

 

.link{

              display:block;

              width:150px;

              padding:15px;

              margin:15pxauto;

              background:white;

              box-shadow:005px0rgba(63,31,0,.5);

              border-radius:10px;

              text-align:center;

              text-decoration:none;

              -webkit-transition:.2s;

              transition:.2s;

       }

 

.link:hover{

              -webkit-transform:rotate(-10deg)scale(2);

              transform:rotate(-10deg)scale(2);

       }

 

.pquote{

                     float:left;

                     width:100px;

                     background:#ddf;

                     font-weight:bold;

                     padding:13px;

                     margin:013px13px0;

                     border-radius:5px;

              }

          

Step 5: Add UI elements in view, include the above classes

 

<core:Viewxmlns:core="sap.ui.core"xmlns:mvc="sap.ui.core.mvc"xmlns="sap.m"

              controllerName="xml_cust_cs.HOME"xmlns:html="http://www.w3.org/1999/xhtml">

          

       <Pagetitle="SAPUI5 Tutorial">

              <content>

              <Labelclass="header"text="Working with XML Views:Using External Stylesheets"/>

               <VBox>

         <HBox>

         <Textwidth="100px"

         text="SAPUI5 XML Overview"

         class="pquote">

              </Text>

          

              <Text

         width="250px"

         text="The XML view type is defined in an XML file. The file name either ends with .view.xml or as an XML string. The                 file name and the folder structure together specify the name of the view that equals the SAPUI5 module name                   within the require/declare concept.">

              </Text>

         </HBox>

<HBox>

<Link

        class="link"

        text="Click to know more"

        href="http://help.sap.com/saphelp_hanaplatform/helpdata/en/91/f292806f4d1014b6dd926db0e91070/content.htm"/>

          </HBox>

          </VBox>

              </content>

       </Page>

</core:View>

 

Step 6: Save the Changes and test the application

  


xml view 4.PNG

xml view 5.PNG


Scenario 2: Using Local Style class in XML Views- Case where simple & minimal CSS involved


When there is a need to style only a particular UI element, with local style class, the below one give you the result


<Pagetitle="SAPUI5 Tutorial">

<content>

         <html:style>

                 .myText {

background-color:teal;

color:white;

padding:4px

                                 }

          </html:style>

<Label  class="myText"  text="Working with XML Views:Using Local CSS Class"/>

</content>

   </Page>

xml view 6.PNG


Feedbacks and suggestions are welcome!


Regards,

Meganadhan S


Filtering Data from an Odata Service in Table in SAUI5

$
0
0

In my previous blogs I have shown how to bind data to a table via Odata Model. Now, Here I would show how to filter the data fetch from an odata service.

The  oData service we would use here is:

 

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

    

If we have to filter an odata service using our service url we have to ‘$filter’ and apply it with the desired equation. For example ,if we have to fetch data for the employees who fall under the CompanyId SAP, then our url should be something like this:

 

Filtering
https://companylistdemo.hana.ondemand.com/refapp-companylist-web/companylist.svc/Employees?$filter=CompanyId eq 'SAP'

 

Now, we will see how to implement this filter in an SAPUI5 project.

 

Generally, we bind Items to a Table somewhat like this:

 

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

 

Lets go through this bindItems() method. This is a method which is extended from sap.m.ListBase.

 

bindItems(sPath, oTemplate,oSorter, aFilters): sap.m.ListBase

 

sPath : path to a list in the model

oTemplate : the control template for this aggregation.

oSorter : the initial sort order(optional)

aFilters : the predefined filters for this aggregation(optional).

 

 

aFilters is the parameter here which we will be using to set the filter for the Table as shown.

 

 

 

aFilter

var oFilters = [ new sap.ui.model.Filter("<Column for filter>","<Operator>", "<Filter Value>") ];

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

 

 

 

If our criteria is to fetch data  for Employees with CompanyID SAP, then our code will be:

 

CompanyID=SAP

var oFilters = [ new sap.ui.model.Filter("CompanyId","EQ", "SAP") ];

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

 

 

Now, Lets create a small application to implement this:

Open Eclipse, Create a New SAPUI5<mobile> project with a View named MainView<javascript view> .

Paste the following code in the “createContent: function(oController)” of the view.js page:

 

View.js

 

 

var oPage = new sap.m.Page({

 

            title: "Company Details",

 

             });

 

             var oItemTemplate = new sap.ui.core.Item({

 

                    key: "{key}",

                    text: "{text}"

 

             });

 

                var combobox = new sap.m.ComboBox("cmb1",{

 

                    items: [ {

                           "key" : "*",

                           "text" : "All Data"

                    },
{

                             "key" : "SAP",

                           "text" : "SAP"

                    },
{

                           "key" : "ITelO",

                           "text" : "ITelO"

                    }
],

                 template: oItemTemplate,

                    selectionChange: oController.Selection

             });

 

             var oLabel= new sap.m.Label("lbl",{

 

                    text: "Select a Value"

             });

 

             var oTable = new sap.m.Table({

 

                     id : "Countries",

                    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}"

 

                    })

 

 

                    ]

 

             });

 

             var oFilters = null;

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

             oPage.addContent(oLabel);

             oPage.addContent(combobox);

            oPage.addContent(oTable);

 

 

 

 

             return oPage;

 

 

 

Paste the following code in the “onInit : function()” method of the controller.js page

 

 

onInit : function()” method of the controller.js

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);

 

 

 

 

Paste the following code in the below the onInit() method of the controller.js page

 

Selection: function(evt)

 

 

Selection : function(evt) {

                                        var oFilters=null;

                                        var oSelectedKey = sap.ui.getCore().byId("cmb1").getSelectedItem().getKey();

                                        if(!(oSelectedKey=="*"))

                                        var oFilters = [ new sap.ui.model.Filter("CompanyId","EQ", oSelectedItem) ];

          sap.ui.getCore().byId("Countries").bindItems("/Employees",sap.ui.getCore().byId("first_template"), null, oFilters);

            }

 

 

Now save and run the application.

 

chrome.jpg

 

 

Great!!!

oModel.read, JSON.parse & JSONModel

$
0
0

While developing SAPUI5 applications there would be scenarios where you can’t set the oModel directly to an UI control (e.g.: sap.m.List or Table). We need to massage the data and change it to a structure that fulfils the requirement then set it.

 

We had one scenario wherein the back-end system was sending JSON data with a quite complex structure. NW gateway needed to expose the data into oData.

 

There were two options:

  1. Break the JSON into different operations/entities using ABAP and link them in NW gateway project
  2. Just pass the JSON to UI client side as a string and convert it into an JavaScript object

 

We had chosen the second option to avoid lots of ABAP work at NW gateway. NW gateway is not very friendly for complex or deep structured oData services.

 

Here I will explain the steps:

  1. Expose a NW gateway oData that responds the JSON as a string
  2. Make a oModel.read (HTTP GET) call to get the string at client side
  3. Convert the JSON string to a JavaScript object
  4. Convert the main JavaScript object to smaller objects as per your need
  5. Create JSON Model and map it to your control

 

  1. Expose a NW gateway oData that responds the JSON as a string

 

JSON.PNG

  2. Make a oModel.read (HTTP GET) call to get the string at client side

 

ui5.utils.getData = function(ojson){

  var sServiceUrl = "/sap/opu/odata/sap/ZGW_REST_SRV";   

// create OData model instance with service URL and JSON format

  var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true );

  try {

   oAbort = oModel.read("/AGREEMENT('')",

                              undefined,

                              undefined,

                              false,

                              function _OnSuccess(oData, response) {

                                     window.ojson = oData;

                                 },

                              function _OnError(oError){                               

                                 }                            

         );

  }

   catch(ex) {

   alert(ex);

  }

}

Output:

ojson.PNG

oData.PNG

 

3. Convert the JSON string to a JavaScript object

 

var vjson = JSON.parse(ojson.AGREEMENT_JSON);

Parse.PNG

 

4. Convert the JSON string to a JavaScript object

 

      loop through vjson object to create your own json objects. In this example I am directly using vjson to create the JSON model.

 

5. Create JSON Model and map it to your control

 

sap.ui.jsview("ui5.ui5", {

  getControllerName : function() {

  return "ui5.ui5";

  },

  createContent : function(oController) {

  var vjson = JSON.parse(ojson.AGREEMENT_JSON);

  var list = new sap.m.List("list", {

     headerText: "Quote List",

     growing: true,

     growingThreshold: 4,

     growingScrollToLoad: false

  })

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

  list.setModel(oModel);

  var StList = new sap.m.StandardListItem("StList", {

  title: "{id}",

  description: "{type}"

  });

  list.bindAggregation("items", "/",StList);

  return new sap.m.Page({

  title: "Quote",

  content: [ list ]

  });

  }

});

ou.PNG

Output

Why SAP Fiori? .....Connecting Dots.....

$
0
0


SAP Fiori – meaning ‘flowers’ in Italian

 

Lately everyone is asking what is this Fiori and its buzz …… do I need it?….nope!! we will see later when it comes

(the same people who thought IPad was nothing but a giant iPhone(no phone big screen device)…..which turned out to be the first desirable tablet PC on which they perform most of the work now)

 

 

SAP Fiori definition from SAP– (check the highlights below)

 

https://support.sap.com/release-upgrade-maintenance/release-strategy/portfolio/software/simplified-user-experience.html#tabSelector#0_0

 

 

SAP Fiori Demo

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

 

Explain the architecture & a business example(classic GUI to new Fiori UX)?   http://www.youtube.com/watch?v=l-Rj7rXibSA

 

Need too minuscule technical details?


Demo with underlying technical details SAP UI5      http://www.youtube.com/watch?v=r-QszpA-HiI

 

 

Worried about Netweaver Gateway License? – “It’s Free with your existing named licences”

 

  1. You heard me its free

 

Blogs for reference –

http://scn.sap.com/community/gateway/blog/2011/10/17/thoughts-on-netweaver-gateway#comment-333317



In simplistic terms, SAP now include NW Gateway licensing with existing named user licenses. This has the obvious caveat that you wont use NW Gateway for anything beyond what the user is licensed to do.”

http://scn.sap.com/community/ui-technology/blog/2013/05/20/fiori-arrives--first-impressions-and-thoughts



What I am sure about is that the availability of Net Weaver Gateway for all SAP customers without additional licensing costs greatly simplifies the Fiori licensing discussion.”

 

Talk about User Experience huh…… see the next steps on its way

http://scn.sap.com/community/ui-technology/blog/2013/10/18/sap-fiori-ui5-meets-leapmotion

 

Cloud Integration?

http://scn.sap.com/community/ui-technology/blog/2013/10/21/cloud-options-for-fiori-and-fiori-like-apps

 

What is available out of the box?

SAP Central Note for reference –

1959274 - Release Information Note: SAP Fiori transactional apps for SAP ERP 1.0

1959305 - Release Information Note: SAP Fiori transactional apps for SAP CRM 1.0

 

RAPID DEPLOYMENT SOLUTIONS (RDS) now have Fiori as a component(both can be deployed together)

 

For example check latest SAP CRM RDS version

1958660 - SAP Best Practices for the SAP CRM rapid-deployment solution V6.703


It includes Fiori RDS

2020101 - SAP Fiori Apps rapid-deployment solution V3.20

 

.

.

SAP Enterprise Portal and SAP Fiori Common Architecture Recommendations

 

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/60f9f0b6-9c39-3210-9284-843cd5ec3a70?QuickLink=index&…

.

.

.               everything said fine and done but…………………….

.

Mobility??????????..............the biggest question is it solved by this????????  & how do I approach it??????????

http://scn.sap.com/community/mobile/blog/2013/11/28/why-isnt-mobility-getting-started-at-my-company-how-can-fiori-help

 

SAP Fiori and Mobile Portal - Run Best Together!

 

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/e0ea525c-68fb-3010-de8a-bc9f153ccfd4?QuickLink=index&…

 

 

SAP Fiori and Offline Capabilities and as a Mobile App................

 

SAP Fiori Client

 

 

P.S: This blog is just to help who are having this question, nothing personal. And thanks to Narottam Pant, who compiled it.

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 .

Experiences with Development of Fiori-like Apps, SAP UI5 and some Best Practices

$
0
0

In  my SAP TechED&&d-code wrap up  I explained why I believe that SAP UI5 will become SAP’s most important UI technology. But where are we right now? What are the challenges when you develop and implement Fiori-like applications?

 

Starting with ABAP on HANA

 

I blogged about my first experiences with SAPUI5 in 2012 in the context ABAP on HANA: http://scn.sap.com/community/abap/hana/blog/2012/11/02/analytical-abap-for-hana-applications-characteristics-unique-selling-points-and-first-programming-idioms At this time my JavaScript know how was quite limited.

frontend.JPG

In above picture you can see an UI5 application created in 2012 having a shell in gold reflection design – at this time there was no Fiori and no Blue Crystal theme.   In the mean time many things have changed: SAP developed now controls together with design guidelines and principles that define Fiori apps. Now UI5 is evolving from a technology for occasional platform users (and this is the meaning of the acronym “opu” in SAP Gateway context) to a general purpose UI technology.

 

After I started with UI5 very early I put my focus on other UI technologies due to the shortcomings of early UI5 versions but since some months I started to work with UI5 again. In the following I will discuss some aspects of UI technology strategy, UI development and implementation.

 

Which is the right technology for my development project?

 

I think the answer which UI technology to choose is very simple:

  • SAP Screen Personas is the right choice when you want to give an existing ABAP Dynpro and perhaps WDA (non-FPM) application a UI.
  • FPM is the right choice when the UI should be configurable and when complexity is so high that you need a stateful approach: you have a complex data footprint on the frontend, locking is needed and there are many operations that don’t follow the CRUD resp. Query pattern. FPM/NWBC is a also necessary when need good integration into ABAP Dynpro (Object Based Navigation).
  • Take Fiori / UI5 otherwise. Try to use existing frameworks like BOPF/SADL/BW Easy to create OData models. Do integration with ABAP Dynpro using SAPgui for HTML and embed WDA as well as SAPgui for HTML resp. Personas in Fiori Launchpad unless you can’t provide a complete set of Fiori-like apps for the endusers.
  • Do you want to develop and extraordinary application with new user interaction patterns that is completely different from ABAP Dynpro or Web Dynpro technology? Then choose UI5.
  • In mobile development you should consider building hybrid apps using Cordova and the plugins for SMP called Kaspel.  I think this getting better and better since the HTML5 standard is now declared for complete and web applications will get more and more properties of mobile apps since they can access the device interfaces.

 

Reponsiveness – easily done?

 

Fiori apps are responsive, they have a fluid design and you can use them on any device – really? I think this is more complicated. For certain purposes the UI must be complex even when simplifying the process and chaining Fiori apps for example. These are my tips and “tricks”:

  • Test your Fiori-UI early on the target device: are the chosen controls the best choice on the tablet for example? Does the keyboard behave well when popping up?
  • Think about developing own UI5 controls if the existing ones don’t look well on a small device.
  • Optimize your application for the target device. This doesn’t mean that you have to implement an adaptive design but sometimes a compromise is necessary.


Possible Pitfalls when using Open Source JavaScript Libraries

 

One of the greatest advantages of the UI5 world is that you can use existing JavaScript libraries like d3.js, Crossfilter or DC. Do you need inspiration? Just look at amazing visualizations like the one here: http://www.nytimes.com/interactive/2012/02/13/us/politics/2013-budget-proposal-graphic.html?_r=0

 

But be warned and don’t expect that it will be so easy like in the SAP world: some of the frameworks don’t have a proper internationalization so you can get problems since they some of them won’t display date information not in your language and so on. And please be warned to use any code snippets for find on the web: I saw Fiori apps crashing in the Fiori Launchpad since they use global variables. Don’t forget that the Fiori Launchpad is a JavaScript application, too.


Development of Fiori-like and Fiori Apps and implementation of Fiori Launchpad

 

Fiori-like applications are easy to build and you will find many valuable sources here in SCN – just follow the blog og DJ Adams. I think development of Fiori-like apps is not that complicated since it is well supported by SAP UI5 resp. Open UI5 library. Please remark that Fiori apps have to be certified when you want to call them “Fiori” – otherwise they are only “Fiori-like”.

 

Don’t underestimate the effort of implementation the Fiori Launchpad and Portal integration. Fiori Launchpad is an application in the ABAP backend and most likely you will need a new ABAP system. This system will serve as a frontend server containing all UI5 applications and will be also a SAP Gateway hub. A web dispatcher (or reverse proxy) will help to deal with the same origin policy restriction. But this has an impact on your system landscape and please be prepared that you will have to update the UI libraries in the frontend server as well as gateway libraries on this server as well as on the backend frequently. So Fiori will add additional complexity to your systems landscape which is the price for simplification of UI as well as application development.

 

The integration of Fiori Launchpad into the portal needs special attention, too: how do you harmonize portal roles with Fiori Launchpad Roles? What happens if a user has different roles? What about SAP user names if you have different backend systems? How do you integrate CRM Web UI and Fiori Launchpad?


Moving from ABAP to the SAP UI5/SAP Gateway World

 

When discussing UI5 development with ABAP developers I often experience some misconceptions about the technology:

  • An OData service is different from an RFC. In fact it is a kind of middleware between the UI and the backend but it is also part of the UI. Usually one OData service corresponds to one Fiori application and reuse in different UI5 applications will cause much testing effort and much trouble so you should avoid it. And this is the main difference between BAPI and OData-Service: a BAPI is made for reuse and in UI5 context reuse is considered as harmful. So when designing OData services reuse should be done at the layer of implementation.
  • If you come from the ABAP world you have many reuse functions that you can use in UI development: display of archived documents, functionality for output management and so on. All this missing in UI5 right now but I think it is only a matter of time when those functions will be there. In fact SAP has already everything we need like CMIS interoperability features as well as solutions like SAP Mobile Documents.
  • UI5 applications are RESTful web applications and their architecture is different from stateful UI technologies like ABAP Dynpro and Web Dynpro ABAP. So the understanding the difference between statefulness and statelessness is most important.
  • You might not believe it but I heard ABAP some developers complain about the usage of XML in OData since XML is considered slow and takes bandwidth. This always makes me smile because from my experience gzipped XML is only 20% bigger compared to gzipped JSON – and, by the way, OData supports JSON serialization, too. In my opionio it is most important that ABAP developers without experience in web development have to learn “new” programming idioms like AJAX. Those techniques will help them to speed up web applications significantly.
  • UI5 is open and allows to create mashups and can be used in Web Dynpro ABAP as well as CRM Web UI. But never forget restrictions like above mentioned Same Origin Policy and security considerations. UI5 applications are vulnerable compared to Web Dynpro ABAP – using Google Chrome development tools you can change data and completely rewrite an existing UI. You have to be well aware of that.

 

In my opinion above examples show that you can’t transfer all best practices know from the ABAP to the new UI technologies. ABAP developers need to achieve new skills and have to learn new paradigms. Especially the combination of stateful UI technologies like Web Dynpro with embedded UI5 is most promising since Web Sockets that are available in ABAP since Release 7.40.


Summary

 

This blog far from being complete since I didn’t write anything about SAP Web IDE which I’ll try out in the near future. This blog reflects my own experience as well as many discussions at SAP TEchEd&&d-code in Berlin and I thank DJ Adams, Robert Eijpe and Owen Pettiford as well as the UI5 team at SAP. In fact I don’t know whether they agree to everything I wrote in this blog entry but I’d like to hear their opinion.

 

I think the blog can be summarized in a few words: UI5 development is well understood and not so the difficult as you might think. Tools, frameworks and libraries are mature but one has to realize that some paradigms differ from traditional SAP UI technologies.

Pagination in sap.m.Table

$
0
0

I was having a requirement something as follows:

I was using sap.m.Table. I had a json Model. But what actually was needed was, the model had 10 records, and were required to be shown in splits of 2.

There was direct solution, had i used sap.ui.Table by setting the navigationMode to Paginator. Unfortunately, sap.m.Table doesn’t have any of that sort (if I am not wrong).

So, I had to do a bit of back of the hand bowling to achieve this. I had placed two buttons named “Previous” and “Next”, then some magical code.

 

So lets get into it. In this example I will be using a model with 7 records to be shown in  splits of 2.

 

Firstly the Design<View1.view.js>

In the CreateContent of the View paste the following code:

CreateContent of View.js

var oPage = new sap.m.Page({title : "Company Details" });

var oTable = new sap.m.Table({

 

id : "Countries",

mode : sap.m.ListMode.None,

headerText: "Details of the Countries",

 

columns :
[
new sap.m.Column({

 

width: "1em",

header: new sap.m.Label({

text: "Name"

  })

}), new sap.m.Column({

width: "1em",

header: new sap.m.Label({

text: "short"

   })

   })

  ]

  });

      varoButton1 = new sap.m.Button({

text : "Next",

id : "Next"

});

 

var oButton2 = new sap.m.Button({

text : "Previous",

id : "Previous"

});

 

  var start = 0;

   var i = 0;

  var rowCount = 2;

oButton1.attachPress(function() {

start =start + rowCount;

oController.populateData(start,rowCount);

});

oButton2.attachPress(function() {

start =start - rowCount;

oController.populateData(start,rowCount);

});

oPage.addContent(oTable);

oPage.addContent(oButton2);

oPage.addContent(oButton1);

  return oPage;

 

 

Secondly, the controller.js

In the onInt() method paste the following Code:

 

onInit() Method of Controller.js

 

 

var data = {

                                               "countries" : [ {

 

 

                                                     "name" : "India",

                                                     "short" : "In"

 

 

                                               },
{

 

 

                                                     "name" : "England",

                                                     "short" : "En"

 

 

                                               },
{

 

 

                                                     "name" : "Australia",

                                                     "short" : "Oz"

 

 

                                               },
{

 

 

                                                     "name" : "New Zealand",

                                                     "short" : "Nz"

 

 

                                               },
{

 

 

                                                     "name" : "France",

                                                     "short" : "Fr"

 

 

                                               },
{

 

 

                                                     "name" : "SouthAfrica",

                                                     "short" : "SA"

 

 

                                               },
{

 

 

                                                     "name" : "Germany",

                                                     "short" : "Gr"

 

 

                                               }
]

 

 

                                        };

 

var view = this.getView();

this.app = view.byId("theApp");

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

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

this.populateData(0,2);

 

 

Now , the last part: Coding the populateData method.

Paste the following code in the controller.js file after as a method.

 

populateData Method of Controller.js

 

 

populateData : function(start, rowCount) {

 

             sap.ui.getCore().byId("Previous").setEnabled(true);

             sap.ui.getCore().byId("Next").setEnabled(true);

             sap.ui.getCore().byId("Countries").destroyItems();

 

             for (i = start; i <start + rowCount; i++) {

                    oTableRow= new sap.m.ColumnListItem({

 

                           type: "Active",

                           visible: true,

                           selected: true,

                           cells: [

 

                                        new sap.m.Label({

                            text: sap.ui.getCore().getModel().getProperty("/countries/" + i + "/name")

 

                                        }),

 

                                        new sap.m.Label({

                  text: sap.ui.getCore().getModel().getProperty("/countries/" + i + "/short")

 

                                        })
]

                    });

                    sap.ui.getCore().byId("Countries").addItem(oTableRow);

 

                    if (i ==sap.ui.getCore().getModel().getProperty("/countries/length") - 1) {

 

        sap.ui.getCore().byId("Next").setEnabled(false);

 

                           break;

 

                    }

             }

 

             if (start == 0) {

 

                    sap.ui.getCore().byId("Previous").setEnabled(false);

 

             }

 

       }

 

 

 

Save and Run the Application.

 

chrome.jpg

That's it!!!!

Rightclick in UI5 Components

$
0
0

Hi,

 

This is a tutorial to extend the default UI5 components. I know there are already some nice tutorials to extend UI5 components. But here, we will not only extend a UI5 component, we are going to show you how to add a right mouse click event to a UI5 component!

 

In our tutorial, we will extend the "sap.ui.commons.Link" component with the right mouse click event, but it will work on different UI5 components.

 

For the tutorial we've created a youtube video, Enjoy!

 

 

I hope the tutorial was clear enough! If it wasn't you can find the project on github:

 

https://github.com/lemaiwo/SAPUIRightClickTutorial

 

Thanks to Jeremy Coppey for the audio and his help with the editing of the movie.

 

All feedback is welcome!

 

Also check our website with other UI5 tutorials:

www.sapui.eu

 

Kind regards,

Wouter


SAPUI5 - Pagination in sap.m.Table using skip and top values of OData Service

$
0
0

Hi ,

 

As a part of my project actiities, I need to fetch the data from OData service and show it inside sap.m.Table , however the data was huge and there was a need to implement pagination using $skip and $top values of OData service. There is a chance that user may not view all the records hence , fetching all data in one call and putting it inside model was not advisable hence we went ahead with this approach.

 

Sample implementation is as follows :

 

We created a table using XML View which is following the normal coding and at the footer , we placed a button which calls the method getNextOrders.

 

Inside that method , code is written as follows :

 

 

getNextOrders:function(oEvent){

 

  var sServiceUrl = "ServiceURL";

  var oDataModel = new sap.ui.model.odata.ODataModel(sServiceUrl);

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

  var oUrlParams = "$skip=" + gskipValue + "&$top=" + gTopValue;

  oDataModel.read("/Orders",null,oUrlParams,true,function(oData, response){

  oModel.setData(oData);

  gOrdersModel.setData(oData);

  });

 

  this.getView().byId('idOrdersTable').setModel(oModel);

  gskipValue = gskipValue + gTopValue;

  },

 

gSkipValue and gTopValue are global variable which stores the values to be fetched and skipped. For our implementation , we kept both values as 10. So at a time 10 records will be shown on the screen.

 

Hope this helps in implementing the pagination for others too. Please share any improving points on the same. Will be helpful for me .


Screenshot with demo data from sample service is attached.

 

Thanks & Regards,

Mahesh.

Handling browser Events in XML Views

$
0
0

Introduction:

 

SAPUI5 controls has been built with the necessary events required for it. However there are certain cases, in which additional browser events needs to be added to the controls. "keypress" is a sample browser event for input element. In such cases, we can include browser events using attachBrowserEvent of UI elements (wherever applicable). Adding browser events in JS views is comparatively easier than doing the same in XML views.

 

Purpose: To Demonstrate handling browser events in XML views

Note:

1. Please check SAPUI5 Demokit Documentation for each individual controls whether they have option to add this additional event to it.

2. To know more about additional possible events, please check :http://www.w3schools.com/js/js_events_examples.asp

 

 

Sample Scenario:

 

Prevent user to enter only alpha numeric value in the input field and show message as well.

 

Implementation:

 

Step 1: Create a Sample UI5 application project by selecting XML view as the view type.

 

Step 2: Add a Label and Input field with an id to it as below

 

              <content>

                  <VBox>

                    <Labeltext="User ID"/>

                    <Input

             id="myInp"

             type="Text"

             placeholder="Enter  ID">

                    </Input>

                </VBox>

         </content>


Step 3: In Controller class, add the method onAfterRendering as below

 

            onAfterRendering: function() {

                                                  },

 

Step 4: Inside onAfterRendering,get the id of  input field and attach the browser event for it. Also add the logic that needs to be called when this browser event is fired. Now the method would look like:

 

onAfterRendering: function()

{

     this.getView().byId("myInp").attachBrowserEvent("keypress",

function(event){

     event.stopImmediatePropagation();

var regex = new RegExp("^[a-zA-Z0-9]+$");

var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);

if (!regex.test(key))

{

                                      sap.m.MessageToast.show("Special Characters not allowed",{

     my:sap.ui.core.Popup.Dock.CenterCenter,

     at:sap.ui.core.Popup.Dock.CenterCenter });

                                      event.preventDefault();

                                      event.stopPropagation();

returnfalse;

}

}

);

},

 

 

Step 5: Save,Build and Test locally. Output of this will block the user to enter any special characters and also throw a message in screen.


Output.PNG

 

 

We can also define and handle the other browser events same as the above one. Give a try

 

Suggestions and Feedbacks are welcome!

 

Regards,

Meganadhan S

Web Worker in SAP UI5

$
0
0

Hi,

 

As we know Web worker is comes under HTML 5 environment.

Here we will discuss some new ideas about web worker and drawback about our old function calls.

 

Introduction:

 

1. Web Worker- executing scripts in an HTML page, the page becomes unresponsive until the script is finished

2. Web Worker- Runs in the background, independently of other scripts

 

Advantage of Web Worker- function:

 

1. Asynchronously via callback functions

2. No regression to other thread

 

Drawback in Normal function call (SAP UI5 environment):

 

1. It create single thread to all functions

2. It is difficult to use setTimer function to multiple function calls in single click

 

Worker function:

1. How to create instance -

 

       new Worker("YourJAVASCRIPTNAME.js")

      w.onmessage = function(event) {

       }

      Here we will get our response by using postMethod()

 

Principles:

 

1. It open one new thead,and create an instance to your function

 

Uses:

 

1. Asynchronous way to run function calls

2. we can set a timer while executing more function calls in a single shot

 

Note:

1. we can't able to get data from our parent classes/object.

 

Please shoot your questions

 

Links: http://www.w3schools.com/html/html5_webworkers.asp

 

Thanks,

 

Karthik A

My dCode session: CR717 SAP Web IDE WYSIWYG

$
0
0

Hello everybody,

 

here I'd like to give you a wrap up about my dCode session CR717 about the SAP Web IDE WYSIWYG aka Layout Editor which I held in Berlin on Tuesday, 11th November 2014. I did the preparation together with my colleague Tino Butz, who held the same session in Las Vegas.

session.png

SAP Web IDE SCN Homepage (lots of tutorials and info material)

 

The SAP Web IDE is a cloud based development environment to develop SAPUI5 applications. It is already released to customers, you can buy it or try it out for free. The Layout Editor is part of the SAP Web IDE (technically speaking it is a plugin for the SAP Web IDE), but NOT released to customers yet.

 

In my session I first introduced the SAP Web IDE and after that I walked through the tutorial "Less Coding, More Designing: The New SAP Web IDE Layout Editor" from my colleague Lisa Monshausen(a how-to guide "How to use the Layout Editor of SAP Web IDE" by Wolfgang Scheeris also available).

 

WYSIWYG Layout Editor:

  • is not released to customers yet
  • it is a "developer preview" to get your feedback
  • currently supported in Chrome
  • try it out on our trial landscape

 

Layout Editor sections

Here are the different sections from the layout editor:

layout_editor_overview.png

 

Opening Layout Editor

If you have an XML view right click on a file and choose "Open with --> Layout Editor" to start it up in Chrome.

openwith_layouteditor.png

 

Key takeaways

There are several things which make me very excited about the layout editor. First off all: I am a visual oriented person - I'd like to see an instant preview of what I am doing.

 

Quick look

With the layout editor I can have a quick look at my view, without starting the whole application and write code for setting up the navigation.

quick_look.png

 

Palette

In the palette I can get a quick overview of the currently supported controls which are draggable into the view area and can be modified in the layout editor. There are a lot of different controls in UI5 and I really like to snoop around in the different categories like layout or input to see what is available.

palette.png

 

Properties

Buttons for example have a lot of different properties which can be manipulated. In the properties pane I can play around with those properties and see an instant preview of my changes. For me it is really good to see which are the most common properties of a control, so that I am able to learn how to use those controls.

properties.png

 

Drag and Drop

It is pretty handy to grab a control and just place where you want it to be - I mean in contrast to sniffing through XML code and finding the right place "manually".

dragdrop.png

 

Outline pane

In terms of hierarchy the outline pane is pretty useful - it tells me how the view is structured. If I select an entry in the outline pane it selected in the canvas and vice versa.

outline.png

 

Data binding

If you select in the outline pane for example the value of a list item, the data binding pane pops up and there you can see the different properties of the collection.

databinding.png

 

And now we come to my favorite feature:

Instant code changes "preview"

We are all developers and are at home in the code editor - aren't we? If I open the XML view in the code editor and in the layout editor at the same time I can make changes in the code editor, switch to the layout editor tab and immediately see my changes - without saving! There I could continue my manipulation of the view and switch back to the code editor. This goes really "hand-in-hand" and it is great that the Layout Editor produces "human readable" code which is easy to manipulate.

button_manipulation.png

Keyboard support

There is a documentation about the keyboard support available.

 

Q&A

At the end we had enough time for Q&A. Here is a wrap up:

As stated above, the Layout Editor is currently available only on trial and works at the moment only in Chrome.

There are also some complex controls available like the "Grid Layout" and if you drag this control into there are also some example controls in it - same for simple form.

It is possible to display controls which are not supported by the Layout Editor, it means you can only manipulate them through code.

 

Grid example:

grid_example.png

 

Unsupported controls:

unsupported_controls.png

 

TL;DR

The Layout Editor can be a big benefit to quickly put together a layout and manipulate the controls. It works like a charm when editing the file in the code and layout editor at the same time, so you can have a quick view at your changes without saving. Try it out for free with Chrome.

 

Feedback? Problems? Questions?

If you want to provide feedback to the Layout Editor you can put it here.

If you have specific problems or questions I'd kindly ask you to open a new question here in SCN and put in into the SAP Web IDEcategory.

Exporting to Excel from sap.m.Table via csv

$
0
0

Guys some good news, hopefully for many others as well. In this process of learning and playing with SAPUI5 mobile, I have silently got a way out to export the data to excel. To be frank, we can’t directly export the data to excel. It needs to be formed into a csv format and then to excel.

 

So, lets begin.

 

Go to eclipse---New SAPUI5 project<Mobile>--Give the view name as “View1” (js view).

 

Firstly, the Design

Paste the following code in the createContent() of  View1.view.js (Design):

 

createContent() of  View1.view.js

 

 

var oPage = new sap.m.Page({

 

                    title: "Company Details"

             });

 

var oButton = new sap.m.Button({

 

                    text: "Export",

                    press:[ oController.Export, oController ]

             });

 

 

             var oTable = new sap.m.Table({

 

                    id: "Countries",

 

                    mode: sap.m.ListMode.None,

 

                    columns: [ new sap.m.Column({

 

                       width: "1em",

                         header: new sap.m.Label({

                           text: "Name"

 

                           })

                    }),new sap.m.Column({

 

                           width: "1em",

                            header: new sap.m.Label({

                            text: "short"

                            })

                      })

                    ]

              });

 

 

             var template = new sap.m.ColumnListItem({

 

                   id: "first_template",

                      type: "Navigation",

                      visible: true,

                      selected: true,

                      cells: [ new sap.m.Label({

 

                           text: "{name}"

 

                    }),new sap.m.Label({

 

                           text: "{short}"

                      })

 

                   ]

              });

               oTable.bindItems("/countries", template, null, null);

               oPage.addContent(oButton);

               oPage.addContent(oTable);

              return oPage;

 

 

 

 

Now, Lets create the model which will hold the data.

For that paste the following code in the onInit() method of the controller.js file:

 

 

onInit() method of the controller.js

 

 

var data1 = {

 

                    "countries" : [ {

 

                           "name" : "India",

                           "short" : "In"

 

                    },
{

 

                           "name" : "England",

                           "short" : "En"

 

                    },
{

 

 

                           "name" : "Australia",

                           "short" : "Oz"

 

                    },
{

 

                           "name" : "New Zealand",

                           "short" : "Nz"

 

 

                    },
{

 

                           "name" : "France",

                           "short" : "Fr"

 

                    },
{

 

                           "name" : "SouthAfrica",

                           "short" : "SA"

                    },
{

 

                           "name" : "Germany",

                           "short" : "Gr"

 

                    }
]

 

      };

 

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

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

 

 

Now the functionality which would export the data to excel.

 

 

For that paste the following method in the controller.js file

 

JSONToCSVConvertor

 

JSONToCSVConvertor : function(JSONData, ReportTitle, ShowLabel) {

 

         

// If JSONData is not an object then JSON.parse will parse the JSON

// string in an Object

 

   var arrData = typeof JSONData.countries!= 'object' ?JSON.parse(JSONData.countries) : JSONData.countries;

   var CSV = '';

   // Set Report title in first row or line

CSV+= ReportTitle + '\r\n\n';

 

             if (ShowLabel) {

 

                    var row = "";             

                    row= row.slice(0, -1);

                  CSV+= row + '\r\n';

 

             }

 

             //loop is to extract each row

 

             for (var i = 0; i <arrData.length; i++) {

 

                    var row = "";

                  row+= '"' + arrData[i].name + '","' + arrData[i].short +'",';

                  row.slice(0,row.length - 1);

                    CSV+= row + '\r\n';

 

             }

 

             if (CSV == '') {

 

          alert("Invalid data");

                    return;

             }

 

             // Generate a file name

 

             var fileName = "MyReport_";

           fileName+= ReportTitle.replace(/ /g, "_");

 

             // Initialize file format you want csv or xls

             var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);

 

             // Now the little tricky part.

             // you can use either>> window.open(uri);

             // but this will not work in some browsers

             // or you will not get the correct file extension

             // this trick will generate a temp<a /> tag

             var link =document.createElement("a");

       link.href= uri;

 

             // set the visibility hidden so it will not effect on your web layout

 

       link.style= "visibility:hidden";

       link.download= fileName + ".csv";

 

// this part will append the anchor tag and remove it after automatic

  // click

             document.body.appendChild(link);

             link.click();

             document.body.removeChild(link);

 

       }

 

 

And the last part. In the design we added a button, now we need to invoke the above function on the click of the button.

For that past the following code in controller.js as well.

 

Export function in controller.js

 

Export : function() {

 

  var data= sap.ui.getCore().getModel().getData();

  this.JSONToCSVConvertor(data,"Report", true);

 

       }

 

Now our application ready for testing.  Here, we go:

 

chrome.jpg

 

 

Hmmmm, Not Bad!!!!!!!!!

Launchpad Navigation with UI5 Boilerplate

$
0
0

A Launchpad is now (as of version 0.8.0) included in the UI5 Boilerplate, similar to the famous Fiori Launchpad. In contrast to the Fiori Launchpad it is part of the App itself and enables Launchpad Navigation within the App, which could be of interest in case you build a more extensive App.

 

As before the navigation items are generated automatically from the menu definition file (menu.json), in the case of the Launchpad Navigation mode, Tile objects are created and placed on Launchpad of the UI5 Boilerplate.

 

There is nothing special necessary to switch and use the Launchpad, simply update to the current version of the UI5BP. The Launchpad Navigation is now the default navigation mode of the UI5 Boilerplate, although the LeftMenu Navigation (via Master Page) is still available and can be activated via configuration or by a URL parameter at any time.

 

Launchpad Navigation

So how does it look like? Here some screenshots of the Launchpad on a tablet:

UI5BP_Launchpad8-iPad.png


On the detail pages there is now a Home Icon in the upper right corner which allows navigation back to the Launchpad:

UI5BP_Launchpad9-iPad.png

To add further pages and therefore Tiles to the Launchpad within the UI5 Boilderplate nothing has changed. You simply maintain a new entry in the menu.json file and add the corresponding ui5 view and controller file. That is all! More details can be found in the dedicated post “Add Page to UI5 Boilerplate”


Configuration of Navigation Mode

The configuration of the navigation mode is done via the file app/config.js:

UI5BP_Launchpad6-config.png

Besides this, it is possible with the URL Parameter mode=LeftMenuNavi to overrule the configuration and start the App in LeftMenu Navigation mode:

 

http://....../index.html?mode=LeftMenuNavi

 

Screenshots on tablet with Left Menu Navigation:

UI5BP_Launchpad7-iPad.png

As I was asked just yesterday, yes you can use the UI5 Boilerplate for our own purposes and you could do almost everything with it, whatever you like, as it is licensed by Apache 2.0 license, which is a very friendly license.

Related Information:

OpenUI5 development on Node.js

$
0
0

The Beginning

After working for around 9-years on Java, finally got my first chance to work productively on Pure Web Application. It is based on OpenUI5 technology, but still has server side using Java environment (OSGi runtime). Got my hands dirty into javascript, jquery, openui5 to that extend that I started giving session to colleagues joining later point of time.

Then it so happened that during my transit from Delhi to Bangalore, I happened to be bored by the time I had stepped on the airplane. The flight had delayed and hence I switched on my laptop to search for peace. We all have this list somewhere stating 'things-to-do' and 'books-to-read'. I had one similar book about node.js (the node beginner book - Manuel Kiessling) and I began to read it, considering that by now I understand the design-patterns of javascript. In the next 3hrs and the weekend that followed, I was hooked onto node.js.

 

The Problem Statement

"Behind every successful man, there is a wife...and an unsuccessful man, a mistress" - A quote from the web-world, where I would say, my journey to Web-development has begin to be successful because of my better half. My wife (herself a web-developer), asked me what real-world-problem are you trying to solve. I didn't have an answer at that point of time, but soon I realized the complexity of my day-today-work (of using complex client/server infrastructure) can be reduced big time to represent any simple web-application.


"To build a simple web-application with single program language aka javascript (UI, to server, to database)" -- I have tried to be summarize it without really revealing what I am building -- but this would do as for now.


Toolset & Installation

Every good development needs variety of tool-set. In this case there is just the IDE (Eclipse Java EE IDE for Web Developers - Kepler version) and the update site of 'Node Eclipse'[1] (Nodeclipse - Installation Instructions).


Node JS Installation for Windows:

  • Download the msi from the link
  • Install using the msi file.
  • Also, can have a look at youtube video in case facing trouble with it.
  • To test go the command prompt (Goto Run --> type 'cmd' and hit enter)
    • node -v : this would give you version of Nodejs
    • npm -v : this would give you version of NPM[2]

Create project in Eclipse

  • Open the Node perspective in the Eclipse IDE

1_Workbench.jpg

  • Select 'Node.js Project'

2_CreateProject.jpg

  • Let us create empty project, so that we understand the project structure, even though there is possibility of some things out of the box

3_NewProject.jpg

  • Now the project created has initial project structure

4_InitialProjectStructure.jpg

Understanding other libraries & components

Express

It is a simple and most commonly used REST implementation on nodejs. It helps in setting up HTTP server and handle REST calls.


Jade

Nodejs works with template engine to render web-pages. There are number of such template engines and jade is one of them which works with express. Others can be swig etc...


package.json

If you come from the ant world, this is sort of build.xml, if you come from maven world, this is sort of pom.xml. While I myself is still learning what things can be specified in package.json - it is the starting point for defining nodejs module.


Writing the code

Refer to the attached project which contains the complete project. Due to size limit no 'node_modules' are included[3].

Defining package.json

Contains the definition of the module we are building. Two major section of json are discussed:

  • Dependencies: This section of the json talks about the other node_modules required to build our module. Like 'Express' and 'Jade' are required, we would add the same as part of dependencies.
    • Asterisk marks to fetch the latest value
    • Tilde marks that this version or higher.
  • Main : This informs the Node JS which is the first Javascript file which needs to be invoke.


Defining app.js

This is sort of our main program (like in java). While this blog would not talk about how to write node.js module programs, there are some parts I have discussed below

  • require statement : Just like import statement (in Java) or include statement (in C/C++)
  • app.use( express.static(<file path >) ) - It is a way for exposing specific folder which would contain the static resource (which browser can request for)
    • This would come in use in the second part of the blog, where we would do 'offline' web-ui development by bundling OpenUI5 SDK.
  • the app.set method calls - Specifying Jade as the template rendering engine. This helps in dynamically generating Web Pages on server and sending to client.
  • app.get - Registering to the REST call at the domain URL (like http://localhost:80/)
  • app.listen - Simply starting the HTTP server.


Defining home.jade

The most interesting part which really helps in consuming the OpenUI5 CDN URL for building our Web Project. The rendering-algo of the Jade Template engine is based on line-breaks and indentation.

  • The first 'script' tag entry actually helps in setting the OpenUI5 bootstrap entry.
  • init.js -- Utility which actually is required to load some pre-defined functions on the client side
  • home.js -- Inline 'script' which is executed as soon as the page is loaded and does some initial registration and then fetch our Home Shell and place it in our Web Page.
  • Remaining part is just the anchor point which is used to place our complete shell.

In our example we have just used the unified shell example.

Project Structure

5_FinalProjectStructure.jpg


Output

A simple shell application which can be grown into full-blown application. Use modulus.io or microsoft azure which provide node js based hosting solutions.

6_Output.jpg


Bonus (Offline Development)

It is always possible that we would like to work offline (say sitting in airplane). As we are using CDN, this would not work out. We talked earlier in the blog where we are registering folder as 'public'. If we place the relevant OpenUI5 SDK js in specific folder and refer the same from our home.jade file we should be able to build our application in complete offline mode. Based on the image below, just check the change made in home.jade & the project structure.


NOTE: This is only for DEVELOPMENT and shouldn't be done in PRODUCTION. Mainly because of the size of OpenUI5 (~22MB) and for pointing to the latest version.


7_Bonus.jpg

 

References

[1] - Why Node Eclipse for development? This was the first google hit to do 'Node Eclipse' development (coding/debugging/testing). There are some things provided from Strong Loop (Open Source), but not yet evaluated.

[2] - npm stands for Node Package Manager which is used to resolved dependencies between one node-module to others. There is lot more to npm but for now it is the only part which is necessary for the scope of this blog.

[3] - For running the project, import the given project into eclipse. If you have the 'node-eclipse' installed then do the following:

  • Right click on 'package.json' and select 'Run As...' --> 'npm install'. This will get all the dependencies (make sure proxy settings are fine otherwise fetching npm can create issues).
  • Next, Right click on 'app.js' and select 'Run As...' --> 'Node Application'. This would launch the application at http://localhost:80

Clear SSO Cookies in Desktop/ Mobile Application

$
0
0

Hi,

 

While develop our SAP UI5 application by using SAP as a backend server definitely we need to focus on this SSO Cookies .

 

What is SSO?

 

1. SSO Stands for SINGLE SIGN ON

2. User Enters his application by using his correct credentials, At this time Mobile/Desktop Browser will catch https Catch data and stores that catch information in local memory.

 

Problem:

 

When user logoff his application and he tries to enter his application once again with wrong credentials. SSO Cookies will take that old credentials information to enter application.

 

This make big problem in development.

 

For Mobile/ Tablet:

 

Solution:

 

1. Need to clear catches and Data

2. CallNativePlugin ( create one src file to do this actions )

 

Refer: Extending PhoneGap with native plugins for Android | Adobe Developer Connection

 

3. Window.location.reload()

Window.location.reload():

 

 

1. It loads our android project once again and it is useful to delete our catch memories

Refer: Location reload() Method

 

 

For Desktop Application:

 

Solution:

 

1. Create one New BSP Application to MASK SSO Cookies.

 

Refer: SAPUI5 & BSP?

 

 

Thanks,

Karthik A

Updating an oData Service

$
0
0

In one of my previous blogs, I have shown how fetch data from an oData Service. I have used a generic oData service. Now, here in this blog I would show you how to update data into an oData service. To do that we should be have an oData service whichhas the facility of two way binding.

For that purpose we would use the following oData service.

 

http://services.odata.org/V2/(S(hgfvvt31yj5dms3ogd01si4d))/OData/OData.svc/

 

When we create an oData model, we are left with many functions of the model to work with. One such function is update().

This is the function which would be responsible for pushing the updated data to the oData service.

So let us dive a bit into this function:

 

The update function triggers a PUT request to an OData service which was specified during creation of the OData model. The application has to specify the path to the entry which should be updated with the specified updated entry. After a successful request to update the bindings in the model, a refresh is triggered automatically.

 

 

oModel.update()

var oEntry = {};

 

oEntry.Rating = 5;

oModel.update('/Products(1)', oEntry, null, function(){

 

           alert("Update
successful");
},function(){alert("Update failed");});

 

 

So now lets do a small development on that:

Go to eclipse—New SAPUI5 Mobile project—Create a js view<View1>.

Paste the following Code in the onInit() method of controller.js file

 

onInit() method of controller.js

var oModel = new sap.ui.model.odata.ODataModel("proxy/http/services.odata.org/V2/(Shgfvvt31yj5dms3ogd01si4d))/OData/OData.svc/",false);

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

 

 

 

Next lets design the view, So paste the following code in the createContent() method of View.js file:

 

 

createContent() method of View.js

 

var oPage = new sap.m.Page({

 

                    title: "Products",

  });

 

  var oTable = new sap.m.Table({

 

id: "Products",

mode: sap.m.ListMode.SingleSelectLeft,

  selectionChange : [oController.SelectedRows, oController ],

 

 

                    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: "Release Date"

 

 

                           })

 

 

                    }),new sap.m.Column({

 

 

                           width: "1em",

 

 

                           header: new sap.m.Label({

 

 

                                 text: "Discontinued Date"

 

 

                           })

 

 

                    }),new sap.m.Column({

 

 

                           width: "1em",

 

 

                           header: new sap.m.Label({

 

 

                                 text: "Rating"

 

 

                           })

 

 

                    }),new sap.m.Column({

 

 

                           width: "1em",

 

 

                           header: new sap.m.Label({

 

 

                                 text: "Price"

 

 

                           })

 

 

                    }),new sap.m.Column({

 

 

                           width: "1em",

 

 

                           header: new sap.m.Label({

 

 

                                 text: "New Rating"

 

 

                           })

 

 

                    }),new sap.m.Column({

 

 

                           width: "1em",

 

 

                           header: new sap.m.Label({

 

 

                                 text: ""

 

 

                           })

 

 

                    })

 

                    ]

 

 

             });

 

    var oItemTemplate = new sap.ui.core.Item({

 

key: "{key}",

  text: "{text}"

             });

 

 

   var template = new sap.m.ColumnListItem({

 

 

                    id: "first_template",

 

                    type: "Navigation",

 

                    visible: true,

 

                    cells: [

 

                    new sap.m.Label("ID", {

 

                           text: "{ID}"

 

                    }),new sap.m.Label({

 

                           text: "{ReleaseDate}"

 

                    }),new sap.m.Label({

 

                           text: "{DiscontinuedDate}"

 

                    }),new sap.m.Label({

 

                           text: "{Rating}"

 

                    }), new sap.m.Label({

 

                           text: "{Price}"

 

                    }),new sap.m.ComboBox({

 

 

                           enabled: false,

 

 

                           items: [ {

 

                                 "key" : "1",

                                   "text" : "1"

 

                           },
{

 

                                 "key" : "2",

                                   "text" : "2"

 

                           },
{

 

                                 "key" : "3",

                                   "text" : "3"

 

                           },
{

 

                                 "key" : "4",

                                   "text" : "4"

 

                           },
{

 

                                 "key" : "5",

                                   "text" : "5"

 

                           }
],

 

                           template: oItemTemplate,

 

                    }),new sap.m.Button("Save",{

 

                           text: "Save",

                            enabled : false,

                           press: [ oController.Save, oController ]

 

 

                    })

 

                    ]

 

             });

 

    var oFilters = null;

oTable.bindItems("/Products", template, null, oFilters);

oPage.addContent(oTable);

  return oPage;

 

 

Finally in the controller.js file lets code for saving the data.So paste the following code at the end of controller.js file.

 

controller.js

Save: function(evt){

 

       var selectedId=0;

       var newRating=sap.ui.getCore().byId("Products").getSelectedItems()[0].getCells()[5].getSelectedItem().getText();

 

       if(sap.ui.getCore().byId("Products").getSelectedItems()[0].getCells()[0].getText()!="")

 

             {

              selectedId=sap.ui.getCore().byId("Products").getSelectedItems()[0].getCells()[0].getText();

 

             }

 

       var oEntry = {};

       oEntry.Rating= newRating;

       sap.ui.getCore().getModel().update('/Products('+selectedId+')', oEntry, null, function(){

             alert("Data Updated Successfully");

             location.reload(true);

              },function(){

                    sap.m.MessageToast.show("Update failed",{duration:1000});

 

             });

 

},

 

SelectedRows:  function(evt){

 

    if (this.prevSelectedRow) {

 

         var cells = this.prevSelectedRow.getCells();

cells[cells.length-1].setEnabled(false);

cells[cells.length-2].setEnabled(false); 
}

  var selectedRow = evt.getParameter('listItem');

var cells = selectedRow.getCells();  
cells[cells.length-1].setEnabled(
true);  
cells[cells.length-2].setEnabled(
true);

this.prevSelectedRow = selectedRow;

}

 

 

 

Everything is ready, So lets test:

Save and run the application to find the following screen:

 

chrome.jpg

 

 

Now select a radiobutton of the row for which you want to update the new Rating. Now select the new value from the comboBox and click Save.

For example lets update the item with ID 2 by increasing its Rating from 3 to 5.

 

chrome.jpg

 

Done!!!!

Phonegap + OpenUI5 = App published on Play store [Packaging SAPUI5 application]

$
0
0

This blog will help you quickly understand the end-to-end packaging and publishing of SAPUI5 / OPENUI5 apps .This blog will be using Demokit Icon Explorer as the sample UI5 project to be packaged and published to Play Store. Here is a quick outline of the content :

 

  • Node / Phonegap / Cordova installation .
  • Android project creation using command line.
  • Importing project and integrating SAPUI5 code.
  • Build apk and publish on Play Store.

 

 

Node / Phonegap / Cordova installation

 

To start the development process of making a using a hybrid app using phone gap . Node js installation is required . You can download and install the node from the following link : node.js . Once the installation is done, install the cordova and phonegap using the following commands

 

on OS X and Linux:

$ sudo npm install -g cordova

on Windows:

C:\>npm install -g cordova
C:\> npm install -g phonegap

Once installation completes, you can invoke phonegap on command line for further help.

Android project creation using command line:

To create a project for android platform use the follwing set of commands :

    $ cordova create hello com.example.hello HelloWorld
    $ cd hello
    $ cordova platform add android
    $ cordova build

More information can be found at the following url : PhoneGap API Documentation

Importing project and integrating SAPUI5 code:

  1. Launch the Eclipse application.
  2. Select the New Project menu item.
  3. Choose Android Project from Existing Code from the resulting dialog box, and press Next:
  4. If you're using the CLI, navigate to the hello directory you created for the project, then to the platforms/androidsubdirectory. Alternately, if you use the create shell utility, simply navigate to the hello directory.
  5. Press Finish.


Now that the Phonegap project is ready and imported into the Eclipse IDE , time for some SAPUI5 action .


Set-up UI5 Resources :


The most basic requirement for UI5 application is to have resources in place .  Download the resources from OpenUI5 site and place in your imported project in the folowing hierarchy .

phonegap.PNG


Once the resources are available , adjust the index file to load the UI5 Bootlader.


<!DOCTYPE html>

<html>

  <head>

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

  <meta charset="UTF-8">

  <title>OpenUI5 Icon Explorer</title>

  <script type="text/javascript" src="cordova.js"></script>

  <script type="text/javascript" src="js/index.js"></script>

  <script id="sap-ui-bootstrap"

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

  data-sap-ui-xx-bindingSyntax="complex"

  data-sap-ui-theme="sap_bluecrystal"

  data-sap-ui-libs="sap.m">

  </script>

  <link rel="stylesheet" type="text/css" href="css/style.css">

 

  </head>

  <body class="sapUiBody" id="content">

  </body>

</html>

 

Load the application after the phonegap is ready (deviceready event ) . You incorporate this by modifying the index.js file

 

onDeviceReady: function() {

        app.receivedEvent('deviceready');

    },

    // Update DOM on a Received Event

    receivedEvent: function(id) {

    // Tell UI5 where to find application content

    sap.ui.localResources("view");

    sap.ui.localResources("model");

    sap.ui.localResources("util");

    jQuery.sap.registerModulePath('Application', 'Application');

 

    // Launch application

    jQuery.sap.require("Application");

    var oApp = new Application({

    root : "content"

    });

 

 

 

        console.log('Received Event: ' + id);

    }

 

 

Build apk and publish on Play Store

 

Follow the link to publish the application Play Store : Publishing Overview | Android Developers

 

I will share the code on GitHub Shortly .

 

You can get the Icon Explorer app on Play Store (UI5 Icon Explorer - Android-Apps auf Google Play ) or scanning the QR Code below

 

qrcode.png

Pop Up to Accept Input in SAPUI5

$
0
0

In this blog I would show you how to get a pop up over a screen. For getting a popup we will take the help of sap.m.Dialog. This dialog box should be filled with UI elements which comprises the content. This Dialog even has space to add buttons, which would get added at the bottom of the box.

 

Sample Code:

sap.m.Dialog

var oDialog = new sap.m.Dialog("Dialog1",{

                    title:"Dialog",

                    modal: true,

                    contentWidth:"1em",

                    buttons: [/* Add your buttons here */],

                    content:[/* Add your content here */]

             });

 

 

Now, Lets create a small demo app to demonstate the use of this pop-up:

 

Go to Eclipse—New Project—SAPUI5 Mobile, then create a js View<View1>.

Paste the following code in the createContent of view.js file:

createContent of view.js file

var oPage = new sap.m.Page({

 

                    title: "Players Details",

             });

             var oButton1 = new sap.m.Button("Submit", {

 

                    text: "New Entry",

                    tap: [ oController.NewEntry, oController ]

             });

 

             var oButton2 = new sap.m.Button("Save", {

                    text: "Save",

                   tap: [ oController.Save, oController ]

             });

 

             var oButton3 = new sap.m.Button("Cancel", {

 

                    text: "Cancel",

                    tap: [ oController.Cancel, oController ]

 

             });

 

             var oDialog = new sap.m.Dialog("Dialog1",{

 

                    title:"Details ofNew Entry",

                    modal: true,

                    contentWidth:"1em",

                    buttons: [ oButton2, oButton3 ],

             content:[

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

                      new sap.m.Input({

 

                    maxLength: 20,

                    id: "FName"

 

                      }),

 

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

                      new sap.m.Input({

 

                   maxLength: 20,

                     id: "LName"

 

                       }),

 

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

                      new sap.m.Input({

 

                   maxLength: 3,

                   id: "Age" 

 

                    }),

                      ]

             });

             var oTable = new sap.m.Table({

 

                    id: "Players",

                    columns: [

 

                    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"

                           })

 

                    }),new sap.m.Column({

 

                           width: "1em",

                           header: new sap.m.Label({

                            text: "Age"

                           })

                    })

                    ]

             });

 

             oPage.addContent(oButton1);

             oPage.addContent(oTable);

             return oPage;

 

 

Now paste the following code in controller.js file:

Controller.js

NewEntry: function() {

             sap.ui.getCore().byId("Dialog1").open();

       },

 

Save:function() {

 

             var fName = sap.ui.getCore().byId("FName").getValue();

             var lName = sap.ui.getCore().byId("LName").getValue();

             var age = sap.ui.getCore().byId("Age").getValue();

      oTableRow = new sap.m.ColumnListItem({

 

                    type: "Active",

                   visible: true,

                    selected: true,

                    cells: [

                                 new sap.m.Label({

 

                    text: fName

 

                   }),

                                 new sap.m.Label({

 

                 text: lName

 

                  }),

                                 new sap.m.Label({

                  

                 text: age

 

                 })

                 ]

             });

 

             sap.ui.getCore().byId("Players").addItem(oTableRow);

             sap.ui.getCore().byId("Dialog1").close();

             sap.m.MessageToast.show("Saved",{duration:1000});

       },

 

Cancel:function() {

             sap.ui.getCore().byId("Dialog1").close();

       }

 

 

Evrything is ready. Save and run the application.

chrome.jpg

 

Click on the Button “New Entry”. A pop up appears, now fill in the details and press Save.

 

chrome1.jpg

 

 

So, here we are

 

chrome2.jpg

 

Done!!!!

viz charting by json Model

$
0
0
Hi All,
Viewing all 789 articles
Browse latest View live




Latest Images