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

SAPUI5 MVC Pattern and Eclipse Outline View

$
0
0

 

Hi All,

 

I didn’t notice at first, but a few weeks ago, when I opened the Outline view when editing the view and controller files (created by the SAPUI5 plugin using the MVC Pattern), I found out that it was empty.

 

SCNBlog6_01.JPG

 

 

As the code grows and get more complex it became a bit of a pain jumping around to each of the functions, so I decided to look for a solution for this problem.

 


I found out a reference of a very good blog in the stackoverflow forum with the solution.

 

http://www.kajabity.com/2012/02/how-i-introduced-jsdoc-into-a-javascript-project-and-found-my-eclipse-outline/


 

To be brief, to get the outline view working it is necessary to use a JSDOC comment with the following tag:


     /**
     * @memberOf
parentNamepath
     */

 

 

SCNBlog6_02.JPG

 

 

I think it would be nice to have the SAPUI5 plugin creating the initial code with these comments. What you think?

 

 

Best regards,

 

Christian


Native development in SAP HANA and consuming the oData services in SAPUI5

$
0
0

Step 1: Downloading and installing the HANA Studio and Client

Step 2: Installing SAPUI5 toolkit in the HANA Studio

Step 3: Creating system connection with HANA server and creating a workspace repository

Step 4: Creating XS Project in the local repository workspace and deploying on HANA server

Step 5: Testing the XS project, through rest client in a browser

Step 6: Creating an SAPUI5 project

Step 7: Developing the user interfaces, oData Call, integrating SAPUI5 and XS project

Step 8: Testing the application

 

 

Step 1: Downloading and installing the HANA Studio and Client

Navigate to the URL : http://scn.sap.com/community/developer-center/hana

Login with your SCN credentials


HANA Studio installation

Click on ‘Download SAP HANA Studio, developer edition’ (version 1.0.48)

Download the appropriate studio

   SAP HANA Studio version.jpg

Upon download completion, extract the files. Start the installation by clicking on the ‘hdbsetup’.

hdbsetup.jpg

 

HANA Client Installation

Click on ‘Download SAP HANA Client, developer edition’ (version 1.0.48)

Download the appropriate HANA Client

Upon download completion, extract the files. Start the installation by clicking on the ‘hdbsetup’.

 

Connecting the HANA studio to the HANA Repository Client

In HANA studio, navigate to Windows -> Preferences -> SAP HANA Development -> Repository Access

Set the 'SAP HANA Repository Client (regi) location' by clicking on the ‘Browse’ button and navigate through the ‘Program Files’ folder in your system ‘C:\Program Files\sap\hdbclient’ and select the ‘regi’. Click ok.

Repository Access.jpg


Step 2: Installing SAPUI5 toolkit in the HANA Studio

In the HANA studio, navigate to the path ‘Help -> Install new softwares’

Click on Add button. Enter the following details:

NetWeaverOnDemand.jpg

Select the ‘SAP HANA Cloud Tools’ and ‘UI development toolkit for HTML5’

Cloud and UI5 tools.jpg

Click on ‘Next’. It will prompt for credentials, enter your SCN credentials.

Upon download completion, restart the HANA studio.

Navigate to the path ‘File-> New -> Project’ in SAP HANA studio and a new option ‘SAPUI5 Application development’ appears. This ensures that plug-in for UI5 development has been added successfully.

 

Step 3: Creating system connection with HANA server and creating a workspace repository


System connection with HANA server

Navigate to the ‘SAP HANA Development' perspective

Navigate to the ‘Navigator’ view. Right click and select ‘Add System’.

SystemConnections.jpg

Enter the ‘Host name’, ‘Instance number’ and description. Click ‘Next’

System Details.jpg

Enter the 'User Name' and 'Password'

Connection Properties.jpg

HANA studio is connected to a HANA Server.

 

Creating a workspace repository

Navigate to the ‘SAP HANA Repository’ view. Right click and select ‘New Repository Workspace’

RepositoryWorkspace.jpg

Select the 'system connection' created in the previous step. Enter the ‘Workspace Name’ and ‘Workspace Root’. Click ‘Finish’

(P.S. Workspace root is the path where the projects gets created in the local workspace)

A local workspace is created which is connected to the HANA server through the system connection.


Step 4: Creating XS Project in the local repository workspace and deploying on HANA server


Creating the XS project

Select the 'Project Explorer' view

Create an XS project by selecting File -> New -> Project

Select SAP HANA Development -> XS Project, and choose ‘Next’

In the Project Name field, enter 'TestXS'

Choose the repository workspace path/folder where this project needs to be created. Click ‘Finish’

A XS project gets created on the local workspace repository (P.S. the project is only available to developer and is not yet shared across the HANA server)

TestXS.jpg

Now right click on the project and navigate to ‘Team -> Share project’. Select ‘SAP HANA Repository’. Select the workspace repository. Select the repository package (location on the server – if you want to create to a particular folder structure. Navigate to the ‘navigator’ view and under ‘content folder create the necessary folder structutre) and click ‘Finish’.

TestXSafterActivate.jpg

Right click again and navigate to ‘Team -> Commit’ (this save the project locally in the repository workspace).

Right click again and navigate to ‘Team -> Activate’. This will share the project to the HANA server.

 

Creating a schema

Create folder data inside the TestXS project

Right click on the ‘data’ folder. New->File. Enter the name ‘TestSchema.hdbschema’. Click ‘Finish’

hdbschema.jpg

Enter the following syntax to create a schema:

    

schema_name=”TestSchema”;

 

 

Save the file. Commit it and activate it.

Navigate to the navigator view and refresh the ‘catalog’ folder. Observe the newly created schema.

 

Creating a table

Right click on the ‘data’ folder. New-> File. Enter the name ‘TestTable.hdbtable’. Click ‘Finish’

Enter the following syntax to create a schema:

    

 table.schemaName = "TestSchema";
 table.tableType = COLUMNSTORE;
 table.description = "Test Description";
 table.columns = [           {name = "Test Name"; sqlType =NVARCHAR; nullable = false; length = 30; comment = "Test name";},           {name = "Test Id"; sqlType =INTEGER; nullable = false; comment = "Test Id";}          ];
 table.primaryKey.pkcolumns = ["Test Id"];

 

Save the file. Commit it and activate it.

Navigate to the navigator view and refresh the ‘catalog’ folder. Observe the newly created table.

Go to ‘SAP HANA Systems’ view. Open the folder catalog and observe the new schema (TestSchema). Expand the folders->Tables. Observe the newly created table (TestTable). Double-click on the table and the table definition opens up.

table.jpg

 

Creating .xsprivileges file

Right click on the project folder. New-> File. Enter the name ‘.xsprivileges’. Click ‘Finish’

Enter the following syntax

{"privileges":          [  {"name":"Basic","description":"Basic usage privilege"},                {"name":"Admin","description":"Administration privilege"}          ]
}

 

Creating a role

Right click on the project File -> New ->Other -> SAP HANA Development ->Role

role.jpg

Enter the following syntax to create a role:

 Role TestXS.data::TestRole{          catalog schema "TestSchema" : SELECT,INSERT,UPDATE,DELETE,DROP;          application privilege: TestXS::Admin;
}

test.jpg

 

Importing data in table

  Assigning the necessary privileges

  'TestTable' is created by the SQL compiler on the HANA Server. Hence, the user ‘Dummy_User’ used to create connection between HANA studio and HANA       server will not have the necessary privileges to access the table content (alter,drop,insert etc)

  In order to import data to the table, ‘Dummy_user’ is granted the privileges on the ‘TestTable’, using the following steps.

  Navigate to the ‘SAP HANA system’ view. Expand the security folder.

      image.jpg

     Open the user properties by double-clicking on the object. Select ‘Object Privileges’. Search for ‘TestTable’. Click Ok.

     Assign the necessary privileges(Alter, Drop, Insert etc)

      grantprivileges.jpg

 

    Creating and importing the data file (flat file)

    Open a notepad and key in some sample data in the TestTable’s structure (Test Name and Test ID).

           "Roger Federer",852147

           "Andy Murray",963852

           "Novak Djokovic",184527

            "RaefalNadal",985214

    Save it as test.csv file

    Select the project ‘TestXS’. Navigate to File -> Import -> Data from Local File -> Next

     DataFile.jpg

    Select the target system (system connection object). Click on Next

    Select the source file ‘Test.csv’ from the local computer

    In the Target table section. Select the ‘existing’ radio button.

    Click on ‘Select Table’. From the list of catalog select the schema (TestSchema) and the corresponding table (TestTable). Click Ok. Click Next.

     onetoone.jpg

 

       onetoone.jpg

     Click Next-> Finish. Observe the ‘Job Log’ for import status. It should show successful import.

          Joblog.jpg

    Navigate to the ‘SAP HANA system’ view. Expand the catalog folder. Test Schema -> TestTable

    Right click on the ‘TestTable’ -> Open Data Preview

          DataPreview.jpg


Step 5: Testing the XS project, through rest client in a browser


Testing the XS engine

Enter the URL http://<HANA_ServerIP or host_name>:<port_number>

We get a message ‘SAP XS engine is up and running’

 

Creating .xsodata file

Now create a folder services in the TestXS project. Inside the services folder, create TestXS.xsodata file(File -> New-> File)

Enter the following syntax in the .xsodata file:

service namespace "Sample.services" {   "TestSchema". "Sample.data::TestTable"   as "TestXS" ;
}


Create the .xsaccess file

Create the file directly under TestXS project. Enter the following syntax in the file:

{     "exposed" : true
}


Create.xsapp file

Create the file directly under TestXS project. Enter the following syntax in the file:

{}


Activate and commit the project

 

Browser Extensions

Add two extensions to the Google Chrome browser ‘JSON View’ and ‘XML Tree’(by logging in to the chrome store)

Construct the URL to access the xsodata (Navigate to ‘SAP HANA System’ view. Expand the project structure in the ‘Content’ folder. Use the folder structure to construct the URL)

 

http://<HANAServerName>:<port number>/<Folder structure>/TestXS.xsodata

http://<HANAServerName>:<port number>/TestXS/services/TestXS.xsodata

Following xml is returned,

<service xml:base="http://<ServerName>:<Port>/Sample/services/TestXS.xsodata/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app"><workspace><atom:title>Default</atom:title><collection href="TestXS"><atom:title>TestXS</atom:title></collection></workspace></service>t:

 

http://<HANAServerName>:<port number>/TestXS/services/TestXS.xsodata/TestXS?jason

Following xml is returned,

<feed xml:base="http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">

<title type="text">TestXS</title>

<id>http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/TestXS</id>

<author>

<name/>

</author>

<link rel="self" title="TestXS" href="TestXS"/>

<entry>

<id>http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/TestXS(184527)</id>

<title type="text"/>

<author>

<name/>

</author>

<link rel="edit" title="TestXS" href="TestXS(184527)"/>

<category term="Sample.services.TestXSType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>

<content type="application/xml">

<m:properties>

<d:TestName m:type="Edm.String">Novak Djokovic</d:TestName>

<d:TestId m:type="Edm.Int32">184527</d:TestId>

</m:properties>

</content>

</entry>

<entry>

<id>http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/TestXS(852147)</id>

<title type="text"/>

<author>

<name/>

</author>

<link rel="edit" title="TestXS" href="TestXS(852147)"/>

<category term="Sample.services.TestXSType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>

<content type="application/xml">

<m:properties>

<d:TestName m:type="Edm.String">Roger Federer</d:TestName>

<d:TestId m:type="Edm.Int32">852147</d:TestId>

</m:properties>

</content>

</entry>

<entry>

<id>http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/TestXS(963852)</id>

<title type="text"/>

<author>

<name/>

</author>

<link rel="edit" title="TestXS" href="TestXS(963852)"/>

<category term="Sample.services.TestXSType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>

<content type="application/xml">

<m:properties>

<d:TestName m:type="Edm.String">Andy Murray</d:TestName>

<d:TestId m:type="Edm.Int32">963852</d:TestId>

</m:properties>

</content>

</entry>

<entry>

<id>http://<HANAServer>:<Port>/Sample/services/TestXS.xsodata/TestXS(985214)</id>

<title type="text"/>

<author>

<name/>

</author>

<link rel="edit" title="TestXS" href="TestXS(985214)"/>

<category term="Sample.services.TestXSType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>

<content type="application/xml">

<m:properties>

<d:TestName m:type="Edm.String">RaefalNadal</d:TestName>

<d:TestId m:type="Edm.Int32">985214</d:TestId>

</m:properties>

</content>

</entry>

</feed>

 


 

Step 6: Creating an SAPUI5 project


In the HANA studio, navigate to the path File -> New -> Other -> SAPUI5 Application Development -> Application Project. Click Next.

Enter the project name as 'TestUI'. Choose between Desktop or mobile, so that the SAP runtime engine understand whether to render for a mobile application or desktop application

desktopmobile.jpg

Observe that an initial view would be created. Click Next.

Enter the initial view name and select a type of view to be created. SAPUI5 allows us to create :

- JavaScript View

- JSON view

- XML view

- HTML view

These views allow us to work with data in the XML and JSON format, along with the traditional MVC pattern. It also creates a controller along with the view, where the business logic can be implemented.

In our case, we select an 'JavaScript' view.

viewtype.jpg

Click Next. Summary of the SAPUI5 project details is displayed. Observe the libraries that get added with the project. These get deployed on the HANA server in a similar folder structure and is rendered at the run-time.

summary.jpg

Observe the following folder structure for the 'TestUI5' project in the HANA studio

SAPUI5project.jpg


Step 7: Developing the user interfaces, oData Call, integrating SAPUI5 and XS project


TestUI.js file

Open the TestUI.js file and enter the following code in the createContent method:


var oModel = new sap.ui.model.odata.ODataModel("/Sample/services/TestXS.xsodata/",false);

oTable = new sap.ui.table.Table("Test",{visibleRowCount:5});
oTable.setTitle("Test Details");

var testID = new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "TestID"}),                                    template: new sap.ui.commons.TextView().bindProperty("text", "TestId")  ,                     width: "100%"});
oTable.addColumn(testID);
var testName = new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "TestName"}),                                        template: new sap.ui.commons.TextView().bindProperty("text", "TestName")  ,                         width: "100%"});
oTable.addColumn(testName);

oTable.setModel(oModel);
oTable.bindRows("/TestXS");
return oTable;

 

Save the file.

The code creates two columns for the Test Name and Test Id columns.(Observe that in the template we bind the exact column names to the table columns, which allows the data binding to the table)

Data is procured through Model (Observe the path /Sample/services/TestXS.xsodata/, which is same as the url's used for testing the oData services in step 5)

Model is set to the table and the rows are bound to '/TestXS' (observe in Step 5, while creating the .xsodata file the "schema.table" name was given an alias name which in our case is, "TestSchema". "Sample.data::TestTable" as "TestXS". Hence the rows are bound to the /TestXS)

 

In a nutshell,

Data from XS server is procured in a Model.

Table is set to a model, table rows are set to the model structure, columns are bound to the exact model structure name.

 

indext.html file

Point to the SAP UI libraries on the HANA server

Replace

<script src="/esources/sap-ui-core.js"

with

<script src="/sap/ui5/1/resources/sap-ui-core.js"

 

Add the UI libraries for, table and UX3 to support the table UI element.

Replace

data-sap-ui-libs="sap.ui.commons"

with

data-sap-ui-libs="sap.ui.commons,sap.ui.table,sap.ui.ux3"

 

Integrating SAPUI5 and XS project

In TestXS project, create a folder 'UI'


Right click on the SAPUI5 project. Team -> Share Project

Select 'SAP HANA repository' and click Next

In the selected Repository workspace, browse and select the 'TestXS' project and navigate to the 'UI' folder. Click Ok. Click Finish.

Refresh the 'TestXS' project.

Browse through the 'TestXS' project to observe the 'TestUI5' project structure inside the 'UI' folder.

Commit and activate the 'TestXS' project.

 

UIandXS.jpg

Now, the SAPUI5 (TestUI) and XS (TestXS) project is integrated and deployed on the HANA server.



Step 8: Testing the application

Construct the URL to access the indext.html inside the 'TestXS' project. ( Sample -> UI -> TestUI -> WebContent -> index.html )

Open a browser and enter the following URL:

http://<HANAServerName>:<Port>/Sample/UI/TestUI/WebContent/index.html

Table loads successfully with data

output.jpg

SAP UI5 - A Photoshop template of GUI elements

$
0
0

Mockup.png 

 

For me (and I am sure many others!), UI5 has become a really useful toolkit for easily developing web apps and POC's with little effort around the SAP Ecosystem. The OData support, rich controls and business inspired examples lend itself well to the mantra of "Don't reinvent the wheel". At a recent SAP Inside Track event in NY, I made reference to the fact, that while developing a mobile app, I, or a graphic designer, can spend close to 40% of the total design & development phase/hours on the UI. Building "consumer grade" enterprise apps is a different way of thinking for app developers. I am sure many of you, like me, started out with a redefined canvas of boring, grey .NET controls or a "Enjoy" SAP CXTAB_CONTROL. But times are changing and we should all look to the creative and vibrant consumer world of both web and mobile apps to reconsider our methods and processes for developing great apps.

 

When I started working with the UI5 toolkit, I would more often than not, start coding right away, without going through my traditional methods, and ultimately ended up in a frustrating muddled mess. Why wouldn't you start coding immediately .... everything you need is right there? Wrong, planning is everything when it comes to design. Properly designing a app which is going to judged, by today's standards, is not an option - but a requirement. I am not saying every application in your organization needs a UI Designer, but planning should start with sketches, process flows, and subsequently lead to the UI design and  development. When you have a toolkit which has some great looking components, its easy to skip this phase and get cracking. Don't do it. Since I have spent a lot of time developing both web, mobile and traditional apps for the enterprise, my approach and system development life cycle (SDLC) resembles more of a artistic approach and design definition, than a "traditional" enterprise app. Yours can be entirely different, but the point is that I would like to encourage you to consider that a *great* design should be a part of your project goals.

 

The Reason

That's the reason I developed the PSD file of UI5 elements. To make that design planning process quicker, easier and to encourage all of us collectively to make great designs and awesome apps.

 

 

   Screen Shot 2013-07-09 at 9.19.16 PM.png

 

 

The Process

I used the online test suite and replicated the majority of the objects using shapes in Photoshop. Each object has groups/folders categorizing and defining it, both for extensibility and this makes finding a component/object easier. Some objects are not included: Icons and some of the VIZ Charts are not individual objects. Maybe in the near future if I can get some form of 'OK' from SAP for not copying/redistributing their font I will consider it (hint?).

 

Screen Shot 2013-07-09 at 9.15.29 PM.png  Screen Shot 2013-07-09 at 9.20.44 PM.png

 

 

The UI Toolkit

95% of graphic designers will spend time working with a UX/UI in Photoshop prior to coding and this toolkit makes creating those mockups considerably easier. Each object is defined as a shape and can be moved, and styled as needed. Currently the file has 897 individual layers which makes up the +- 8.2 million pixels of UI goodness . Building a new UI mockup should not take long ... create a new file, duplicate the objects you need and get creative. (Please also consider the fact someone is going to need to code this and that your imagination, should be limited by *their* capabilities!)

 

Whats next ...

I am hoping someone else interested in the UI/UX aspect will be able to contribute to the project and consider extending this file and its objects to cover all the aspects. I also hope that SAP will consider releasing its "Master" file to the community as ultimately it will encourage better adoption and use of the product.

 

My challenge to you ....

Does you/your company/partner have a UI/UX designer? Do you think its important to design a UI before coding? Do *you* have any great UI/Designs you would like to share? Post a link in the comments, or better yet, create a post here: https://experience.sap.com/ (SAP Why is experience.sap.com not directly integrated/on SCN??? )

 

You can download the file here:http://www.li-labs.com/downloads/sap%20ui5%20gui.psd

HTML5 is awesome :)

$
0
0

Introduction :

 

     HTML5 has been an evolution from the day it hit the web. Everyone wants to talk about HTML5 even without knowing - What HTML5 is, What it is capable of and What do developers need to focus for developing rich HTML5 application for mobile or web platform. Today I would like to answer these questions on my real life experience as a developer working with HTML5 technology from the last couple of years.

 

Evolution of HTML :

 

      HTML’s update has been very slow in progress for last couple of decades with no much drastic improvements from 1990 – 2010. After the release of HTML 4.01 way backwards in 1999 there wasn't any update for HTML for nearly a decade and people started looking into XHTML 2.0 for development with no backwards compatibility support and its draconian of error handling.


                              html5_awesome_2

     2004 a group of developers from Mozilla and Opera proposed a paper on focusing on developing technologies that are backwards compatible with existing browsers. Finally on 14 February 2011, the W3C extended the charter of its HTML Working Group with clear milestones for HTML5

 

 

                                                       html5_awesome_3

 

What's cool about HTML5 and Do we need it???:

 

                                             html5_awesome_4

 

     There have been lots of potential questions asked by developers who are still pretty much stuck up with the outdated trends of HTML. HTML5 has been able to upbeat with its remarkable features and its potential for creating smarter web applications.

There are quite a few interesting features about HTML5 such as

                                             html5_awesome_5

 

Backwards Compatible:

     Its support for previous versions HTML has kept the developers and organizations safe from updating their web applications. As we might be aware that millions of applications on web are still running on outdated versions of HTML with pretty bad coding practices from developers.

New Semantic Elements:

     Introduction of new semantic structural elements such as header, nav, footer, aside, section in HTML5 has led to neat structuring of page content whereas once it was tedious with div container tags.

  html5_awesome_7

     We also have quite lots of useful semantic elements added on such as Canvas, Audioand also attributes which really makes life easier for developers.

Amazing Built in API’s for building web applications:

HTML5 comes up with amazing set of API’s for building smarter web application such as

Application Cache API, DataTransfer API, Command API, Constraint Validation API,History API, MediaController API, Text Track API, APIs for the text field selections,Canvas 2D Context, Clipboard API and events, Editing APIs, File API, File API: Directories and System, File API: Writer, HTML5 Web Messaging, Indexed Database API, Server-Sent Events, The Web Sockets API, Web Storage, Web Workers,XMLHttpRequest Level 2 and lots more coming in.

In my opinion I consider inclusion of these awesome API’s makes HTML5 sound stronger.

Added support for audio and video:

     The support for audio and video in the browser has led to the demolition of external plugins such as Adobe Video Player and similar other popular plugins. Now the audio and video can be inbuilt played in the browser itself which allows the users to avoid the installation of external plugins which can be a threat to leakage of sensitive data as rightly stated by “Steve Jobs” therefore we can say bye bye to the external plugins in the near future.

 

What isn't HTML5 ?

     I have been speaking quite lot about HTML5 features until now but if you start exploring HTML5 features on your own you would be amazed to see that there are quite a lot of exciting features added on to HTML5 which aren’t HTML5 such as Geolocation, CSS3 animations, CSS3 media queries, and many more.You might be wondering what’s going on ?? Why these features are spoken as HTML5 specifications ?? You might be surprised to hear the answer ” Any sort of enhancement to the web is just pushed on to HTML5 since HTML5 has been brand name for organization and developers to promote their work on web”.

 


What developer needs to focus on ?

     Due to the hype created in the market for HTML5, developers go in search of learning HTML5 and keep wondering Where do I need to start from ?? As a developer myself I believe we just need to focus on the evolving technologies such as Javascript, CSS and HTML individually for frontend development on the web with smarter usage of HTML5 , CSS3 exciting features to keep yourself updated and motivated to move ahead.

 

                                             html5_awesome_6

 


Final Words:

 

     I hope this piece of information helped you across to refresh your thoughts on HTML5. Thanks and Happy Coding :)

 

Check me out @ www.avlabz.com


How to create a simple build script for SAPUI5 with Apache Ant

$
0
0

Another Neat Tool

 

Apache Ant is a tool for automating software build processes. It is lightweight, easy to understand and extensible. And best of all, it has a build-in support in eclipse. In this blog post, I want to show you how you can use Eclipse and Ant to create a basic build file for your SAPUI5 apps. You can download the finished build script underneath the post.

 

Step 1: Setup a project

 

If you don't know, how you can create a basic SAPUI5 development environment and project, then check out this post. When you complete step seven, you have done all preparations for adding a build script.

 

Step 2: Create a build file

 

At first you should ensure, that you have opened the correct perspective in eclipse (Java EE). After that, right click on your project and click "New - Other...". Choose XML File as shown in the screenshot.

xml.pngIn the next dialog, choose "build.xml" for file name and save it in the root directory of your project. After that, go to "Window - Show View - Others" and open the Ant view.

 

ant_view1.png

After that, a new view should appear in your eclipse. I recommend to shift this view to the right side of your editor.

 

Step 3: The Coding

 

Open your build.xml in the editor. Then paste this initial lines to your file:

 

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE project><project name="SAPUI5_APP">          <description>ANT-Script to build SAPUI5-Apps</description></project>

 

As you can see, the build file consists of several XML-tags, which define the project name and the description. When you drag this file from your project explorer view to your ant view, you will see an entry like this.

 

ant_view2.png

Then we will define some global properties, which contains important information about your application and runtime. As you can see, you can also create an external properties file and refer to it from your script.

 

<!DOCTYPE project><project name="SAPUI5_APP">          <description>ANT-Script to build SAPUI5-Apps</description>          <!-- Define the properties used by the build -->          <property name="app.name" value="SAPUI5_APP" />          <property name="app.version" value="1.0" />          <property name="server.home" value="C:/Program Files/apache tomcat/apache-tomcat-7.0.21" />          <property name="sapui5.home" value="C:/Program Files/sapui5" />           <property name="build.home" value="${basedir}/build" />          <property name="dist.home" value="${basedir}/dist" />          <property name="src.home" value="${basedir}/src" />          <property name="web.home" value="${basedir}/WebContent" />          <!-- You can also use an external propterties file -->          <!-- <property file="build.properties" /> --></project>

 

Now it's important to replace two values with individual information.

 

  1. server.home: This property has to refer to your tomcat installation directory.
  2. sapui5.home: This property has to refer to a directory with sapui5 libs. Your best bet would be to create a new directory called "sapui5", where you store all files from the downloaded evaluation package. In this directory, create a new one called "lib", where you store all necessary libraries, which will be needed for your build file. You can copy this libs from "tools-updatesite\plugins". The screenshot shows all required libs.

libs.png

Next step is to define the classpath for compiling. All dependent libraries need to be available for Ant, so you don't get any errors at build time.

 

<!-- Define the CLASSPATH -->          <path id="compile.classpath">                    <!-- Servlet-API -->                    <fileset dir="${server.home}/lib">                              <include name="*.jar" />                    </fileset>                    <!-- SAPUI5 -->                    <fileset dir="${sapui5.home}/lib">                              <include name="*.jar" />                    </fileset>                    <!-- Additional Libs -->                    <fileset dir="${web.home}/WEB-INF/lib">                              <include name="*.jar" />                    </fileset>          </path>

 

After that you can create your Ant targets. A target is a container of tasks that cooperate to reach a desired state during the build process. Put another way, a target is a collection of actions that Ant must take to build that target. Look at the following examples.

 

<target name="clean" description="Delete old work and dist directories">                    <delete dir="${build.home}" />                    <delete dir="${dist.home}" />          </target>          <target name="prepare" depends="clean" description="Create working directories">                    <mkdir dir="${dist.home}" />                    <mkdir dir="${build.home}/classes" />          </target>          <target name="compile" depends="prepare" description="Compile Java sources">                    <javac srcdir="${src.home}" destdir="${build.home}/classes" includeAntRuntime="false">                              <!-- Reference to the defined CLASSPATH -->                              <classpath refid="compile.classpath" />                    </javac>          </target>

 

You can see, that there are dependencies between targets. So when you run "compile", first "clean" then "prepare" and at last "compile" is executed. When you save your file now, you will see in the "Ant-View" these targets, which can be started via double-click. To deploy your application to a server, you will need a war-file. With the next target, we are going to create this file by Ant.

 

<target name="dist" depends="compile" description="Create WAR file for binary distribution">                  <war destfile="${dist.home}/${app.name}-${app.version}.war" webxml="${web.home}/WEB-INF/web.xml">                            <!-- Copy files from web.home-->                            <fileset dir="${web.home}" />                            <!-- Copy all necessary libs from the following directories into WEB-INF/lib -->                            <lib dir="${sapui5.home}/lib" excludes="*branding*,*osgi*" />                            <lib dir="${web.home}/WEB-INF/lib" />                            <!-- Copy classes from working directory into WEB-INF/classes-->                            <classes dir="${build.home}/classes" />                  </war>          </target>

 

When you run this target, you should see an console output like this. Now you can deploy the output war file to your server.

console_out.png

 

Some more Informartion

 

  1. You can do a lot of more things with Ant, e.g. creating Java-Doc, running JUnit tests or deploying your application to a server (have a look at this post for Apache Tomcat). Here is an overview of all Apache Ant tasks.
  2. You can trigger Ant targets from console, too. To do this, you have to install the full Ant library from this site (the built-in support in eclipse can't handle this). Here is link to the official manual.
  3. Besides, you can use Ant as a part of continuous integration.
  4. Apache Ivy is an optional dependency manager for Ant. Very useful, when you have a lot of Java libs in your project.
  5. I can recommend Apache Maven or Gradle as popular alternatives to Ant. It depends on your team, infrastructure, skills and project scope, which build tool you should choose. Read this article, to get a better understanding of the differences: Ant, Maven and Gradle – A Side by Side Comparison.

Simple Mobile SAPUI5 Example Using ODataModel and BlueCrystal

$
0
0

Over the last couple of weeks various developers have contacted me asking me if i knew of a simple mobile SAPUI5 example which used both the ODataModel and the BlueCrystal theme. I have built one and thought i would share it with everyone.

 

The app uses the Northwind OData Service and showcases some of the sap.m and sap.me features like the sap.m.App, sap.m.Shell and sap.me.TabContainer, all up approximately 100 lines of code.

bluecrystal1.pngbluecrystal2.png

You can find the source on github

https://github.com/jasper07/sapui5bin/blob/master/OData_BlueCrystal.html

Secret Behind JSONP

$
0
0

Understanding Your Browser :

 

     As we might be aware that Browser Security Model is considered as the weakest component for the current generation of AJAX and majorly considered as blockage for innovation.

     An attacker from anywhere in the world can insert a script on to your webpage and track all your sensitive details as he might be seeing what you are seeing. The root cause for this sort of script injection is because your damn browser which allows this to happen and barely anything can be done by users and developers to prevent such attack.

     Due to the poor design of security model from the browser vendors, Developers are also a victim. As developers just look around for a solution to get rid of this mess but it’s merely impossible to find a solution rather developers use this technique as a weapon to resolve Access Origin issue and share data via multiple origin's.

This might sound really weird for most but that’s the truth behind JSONP technique.

 

So How Does JSONP Works ?

     JSONP works by constructing a “script” element (either in HTML markup or inserted into the DOM via JavaScript), which requests to a remote data service location. The response is a javascript loaded on to your browser with name of the pre-defined function along with parameter being passed that is the requested JSON data. When the script executes, the function is called along with JSON data, allowing the requesting page to receive and process the data.

This loop hole of inserting the “script” from server side dynamically at run time is the secret behind JSONP technique.

It’s time to code..

Let’s create a function which accepts the URL as the parameter and constructs the script tag at runtime and inserting the source from the remote server. In JSONP each script tag inserted is an individual AJAX call this might lead to unnecessary consumption of memory so once the data is consumed we would remove the script tag dynamically.

function requestServerCall(url) { //Construct the script tag at Runtime  var head = document.head;  var script = document.createElement("script");  script.setAttribute("src", url);  head.appendChild(script);  head.removeChild(script); // remove the script tag once inserted to avoid memory consumption
}

 

By inserting the script tag at run time we basically do a web service call to server via GET method only.

1

 

The web service URL comprises of the predefined callback function along with additional parameters.

Let’s build the complete client side snippet of code

 

<html lang="en"><head>  <title>AvLabz - CORS : The Secrets Behind JSONP </title>  <meta charset="UTF-8" /></head><body>  <input type="text" id="username" placeholder="Enter Your Name"/>  <button type="submit" onclick="sendRequest()"> Send Request to Server </button>   <script>    "use strict";    //Construct the script tag at Runtime    function requestServerCall(url) {      var head = document.head;      var script = document.createElement("script");      script.setAttribute("src", url);      head.appendChild(script);      head.removeChild(script);    }         //Predefined callback function        function jsonpCallback(data) {      alert(data.message); // Response data from the server    }         //Reference to the input field    var username = document.getElementById("username");         //Send Request to Server    function sendRequest() {    requestServerCall("http://localhost/myService.php?callback=jsonpCallback&message="+username.value+"");    }           </script></body></html>

 

 

 

Almost we are done with client side portion of the code, let’s go ahead and write the server side code on PHP which consume the data from the URL like a GET request from client and responses back along with corresponding callback function with JSON data appropriate to the client side request.

Let’s understand the Server side piece of PHP code

    header("Content-Type: application/javascript");    $callback = $_GET["callback"];    $message = $_GET["message"]." you got a response from server yipeee!!!";    $jsonResponse = "{\"message\":\"" . $message . "\"}";    echo $callback . "(" . $jsonResponse . ")";


First, the header() function is used to set the MIME type to “application/javascript”. This tells the client to treat the response as JavaScript. “callback” and “message“ variables hold the parameters passed from client. Finally the appropriate JSON string is constructed and echoed back to client.

That sum’s the topic on JSONP on your local development environment.

Points to Remember:

  • JSONP bypasses the restrictions of the same origin policy by dynamic script injection.
  • Its handy solution if the data flow is insensitive.
  • The callback function’s name is passed to the web service as a parameter.

 

Final Words:

 

Hope this piece of information helped you understand JSONP and its behind the scene secrets..Happy Coding :)

 

Follow me @ www.avlabz.com








 


SAPUI5 Mobile Development Tips – Chrome Tools

$
0
0

Introduction:

 

I believe most of the web developers today are also focusing towards mobile application development since mobile has turned out to be the widely used device across the world by users.


As we know, most of the developers widely use chrome developer’s tools for debugging as it’s one of the best debugging tool out in the market with its awesome features. Even for mobile web application testing I prefer to choose Chrome Developer tools rather moving out to other emulators or testing tools.


Recently chrome as introduced exciting features for mobile web application testing which has made my life easier for testing mobile web application and I hope it helps you out also in speeding up your development.


Getting Started:

 

- > Open the Chrome Developer Tools (Press F12 - Windows) and go ahead and click on the settings icon on the right bottom corner


Tit_Tut_JS_GCDev1_Crop

 


- > Choose the overrides tab option from the settings view

 

settings-chrome.png

 

User Agent - Testing Various Device Resolutions:

 

- > Choosing the respective device user agent adjusts the screen resolution according to its device resolution.

 

Custom Metrics – Custom Resolution:

 

- > You can go ahead and choose your desired screen resolution for testing.

 

Override Geolocation:

 

- > Emulate geolocation position by providing the latitude and longitude values.


Override Device Orientation:

 

- > It's really been difficult for developers to test mobile device orientation via browser its now pretty easier by setting the alpha, beta and omega value to adjust accordingly to respective device orientation.


Emulate Touch Events:

 

- > We can emulate touch events on your browser rather going to device for testing or mocking events in browser is no longer required. (SAPUI5 mocks via data attribute on the src tag which would no longer be required )

 

Final Words:

 

Its indeed necessary for the developer to be aware of this feature use it wisely in the development to speed up. Chrome also has fantastic features on its experiment mode go ahead and explore it.

 


 



Running SAP UI5 (version 1.12.1) on Apache HTTPD over Windows 7

$
0
0

In this blog I would be sharing the steps I followed to install SAPUI5 on my Windows 7 machine

Installing and Running Apache HTTP Server 2.2.25

  1. Got to Apache HTTPD Download Page http://httpd.apache.org/download.cgi
  2. Download & Run the Win32 Binary including OpenSSL 0.9.8y (MSI Installer): (httpd-2.2.25-win32-x86-openssl-0.9.8y.msi) by clicking on the link on this page.
  3. Follow the instructions in the Installer Wizard to complete the Installation (for more details refer: http://httpd.apache.org/docs/2.2/install.html)

Installing SAPUI5

  1. Downloading UI Development Kit for HTML 5 from the link below - http://scn.sap.com/community/developer-center/front-end
  2. Create a sub folder with name “sapui5” in webserver's documents folder, i.e htdocs folder of Apache.org's HTTPD
  3. Unzipped all the .zip (sapui5-sdk-static.zip, sapui5-static.zip, sapui5-mobile-static.zip) to the above “sapui5” folder created in the above step. 
  4. Type http://localhost/sapui5 in the Browser

If a page titles SAPUI5 SDK - Demo Kit appears this confirms SAPUI5 is successfully installed on your machine. You can find further information about playing around with SAPUI5 in this application including the Developer Guide & API References.

Developing a simple List based SAPUI5 Application

$
0
0

I have been for long thinking of writing my first SAPUI5 Application.  I thought I will share my experience especially for beginners like me. I still remember my first simple Sales Order Display screen which I developed using Abstract Portal Component (APC) back in 2005. Since then, I have been developing applications using different technologies – BSP/WDJ/WDA/Visual Composer and have seen lot of changes in the UI space. SAPUI5 for sure is to stay for its own features and benefits. I believe we will get to see more SAP transactions delivered with SAPUI5 in the near future.  I have already been introduced to some of these SAPUI5 screens in HR Renewal and Identity Management applications.

 

I will quickly demonstrate how to build a simple list based screen (Sales Order List Screen) without the need to depend on having a NetWeaver Gateway or an SAP ABAP 7.31 system with  UI Add-on in your own environment.  I would highly recommend to read this tutorial posted by Bertram Ganz. When I started building this application, I got stuck in several places and I was lucky to find solutions posted by others in different places.

 

Prerequisites:

 

  1. NetWeaver Gateway Server - I am using the SAP Netweaver Gateway Service Consumption Demo System offered by SAP. You can register for an access using this link
  2. Install Eclipse IDE (Juno)
  3. Download SAPUI 5 library 1.12.1
  4. Setup Eclipse to include SAPUI5 Plug-in
  5. Download NetWeaver Gateway Eclipse Plugin
  6. Download and Install Tomcat Web Server
  7. Modern browser – I am using Firefox with the Add-ons RESTClient and JSONView

 

Steps:

 

  1. I registered an account to access the Demo NetWeaver Gateway system. I used the Sales Order example - Query - Sales Order (Header). The steps to obtain access and launch SAPGUI are explained in detail. Once you have the URL of your service, you can test it using REST Client to see the output  

          REST.jpg

 

2. Download and install Eclipse Juno editor along with JDK 1.6. Make sure that the JAVA_HOME and classpath are set accordingly

 

3. The downloaded SAPUI5 Library would have the below folder structure

1.jpg

4. To install the SAPUI5 Plug-in, Open Eclipse and navigate to Help > Install New Software.. Provide Name for the Repository and click on “Local” to locate the \HTML5Evaluation_complete_1.12.1\tools-updatesite folder. Select all the components and install them

 

2.jpg

5. NetWeaver Gateway plug-in folder structure is shown below

3.jpg

Similar to the above steps, Open Eclipse and navigate to Help > Install New Software.. Provide Name for the Repository and click on “Local” to locate the \SAPNetWeaverGatewayPluginForEclipse_2.6.400 folder. Select only the required components and install them.

 

4.jpg

After restarting eclipse, under File > New > Other, you will be able to see SAPUI5 Application development and SAP NetWeaver Gateway folders

5.jpg

 

6. Download and Install Tomcat 7 server.  I used the 32-bit/64-bit Windows Service Installer to install Tomcat. The installation is straight forward and Apache website has lot of help documents on this.

 

6.jpg

After installing tomcat, you should be able to see the below folder

7.jpg

Check if your server is working by using http://localhost:8080

8.jpg

Configure the Server in Eclipse so that you could administer it from within Eclipse. Navigate to Window > Show View > Others to bring the Server .

9.jpg

Add the Apache Tomcat v7 server.

10.jpg

 

Now we are ready to build the application.

 

In Eclipse, Navigate to File > New > Other. Most of the tutorials on SCN, show how to create an SAPUI5 application from scratch using "SAPUI5 Application development". I used the NetWeaver Gateway wizard to quickly build an SAPUI5 application with the code auto-generated.

 

Select "Starter Application Project" and proceed with the wizard.

11.jpg

Select "HTML5" in the below screen and provide a Project name

12.jpg

Select SAPUI5 option instead of JQuery Mobile.

13.jpg

Provide the Gateway Service URL. In my case, I provided https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZCD204_EPM_DEMO_SRV/. You can browse the available services by clicking on the "Catalog" button. Click on the Validate button to ensure that the service is valid.

14.jpg

In the below List template, provide the View name, select the Entity Set and columns to be displayed.

15.jpg

Once you click Finish, you will see a project created with files generated.

16.jpg

 

While testing this application initially, I got to see blank screens/no data being retrieved. On researching in SCN, I found out that below changes had to be made.

 

In the file connectivity.js, I had make some changes.

var serviceUrl = "https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZCD204_EPM_DEMO_SRV/";

changed to

var serviceUrl = "proxy/https/sapes1.sapdevcenter.com/sap/opu/odata/sap/ZCD204_EPM_DEMO_SRV/";

 

This is because of Same-Origin Policy which is explained in the E2E Tutorial (which I mentioned above). Since, I am just having a Tomcat server, I continued with this fix.

 

In Index.html

src="./sapui5-1.4/resources/sap-ui-core.js" changes to src="./resources/sap-ui-core.js"

 

In mylistscreenController.js

oTable.bindRows("SalesOrders"); changes to oTable.bindRows("/SalesOrders");

 

After making all these changes, I used the option to "Run on Server". This would open another window within eclipse and show the output.

18.jpg

 

I was also able to test this from the browser by accessing the application on Tomcat server

19.jpg

You could still go ahead and develop the same for a mobile application and package the source code into a Mobile Application which can be deployed on to a mobile device using products like Titanium or Adobe Phonegap (cloud service)

 

I hope you found this informative.

Installing and SAP UI5 toolkit (ver 1.12.1) in Eclipse 4.3 (Kepler)

$
0
0

In this blog I would be sharing the steps I followed to install SAPUI5 plugin on eclipse for Rapid Application Development on my Windows 7 machine

Installing and SAP UI5 toolkit in Eclipse

Prerequisite:

Environment variables CATALINA_HOME, JAVA_HOME & PATH must be set correctly.

 

Steps:

1. Go to System properties.

2. Click environment variables button and add a new variable with the name  JAVA_HOME and set it to the path of top level java install directory.

3. Add another new variable with the name CATALINA_HOME and set it to the path of top level Tomcat install directory.

4. In path variable add a new variable value as %JAVA_HOME%\bin;%CATALINA_HOME%\bin;

 

Steps:

  1. Got to Eclipse 4.3 (Kepler) IDE for Java EE developers http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/keplerr
  2. Follow the instructions in the Install Guide - http://wiki.eclipse.org/Eclipse/Installationto completely Install the IDE.

 

Installing SAPUI5 plugin

Downloading UI Development Kit for HTML 5 from the link below - http://scn.sap.com/community/developer-center/front-end and extract the content in some folder.

Steps:

  1.      Start the Eclipse environment.
  2. choose Help -> Install New Software...

  3. Click Add ... -> Local ....

  4. Navigate to the local update site location, and choose the “tool-updatesite” folder with the folder where you extracted the HTML5 Development toolkit as update source.

  5. Select all plugins and features for installation.

  6. Select the dialog to “Contact all update sites” during installation to find required software

  7. Click Finish to complete the installation process.

  8. Restart Eclipse.

 

To verify the installation:

  1. create a new SAPUI5 Application Project via Eclipse menu File -> New -> Other
  2. create a view with some sample code in the project.

 

Add the Tomcat server in the Servers view of eclipse as mentioned in the link - http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.wst.server.ui.doc.user%2Ftopics%2Ftwinstprf.html  and clicking Run

 

the project should get deployed in the Tomcat server and a view with sample code should get opened in the Browser.

Client-side Session Management

$
0
0

HTML5. It's a mercy!

 

JavaScript developers can use the new Session and Local Storage API to save data in certain scopes. As a result, it's possible to create a real session context in your web application analog to server-side solutions. In this post i want to show you, how you can use advanced JavaScript desing pattern to create a custom SessionManager API for your web-project. You can download the complete source-code of the example at github. Besides, you can check out the live-demo right here: live-demo

 

1. Requirements

 

At first, we have to determine some requirements for the SessionManager.

 

  • It's important to create a JavaScript API, which runs in its own namespace, so we don't have risky side effects to other libraries.
  • We want to store real JavaScript objects, so the SessionManager has to do the complete serialization and deserialization.
  • We want to store our objects in HTML5 Session Storage, so the lifetime of our data are conscious limited. Moreover, we have to store our data in key-value pairs, which means, that we have to save our object as a JSON-String.

SessionStorage.jpg

2. Distinction

 

For this simple example, we don't want to create a generic API, which is able to cast to the correct object-type. We will implement specific functions.

 

3. The Coding

 

As you can see in the live-demo, i used the very popular web front-end framework Twitter Bootstrap as a template for the html-sites (sry, but for such a tutorial i can't use SAPUI5). In this example, I don't use any JavaScript-Componets from Bootstrap, so everything what you see in the following listings is pure JavaScript and jQuery code (so usable in a SAPUI5 app).

 

3.1 main.js

The first js-file called "main.js" represents the interface to HTML templates. These functions are called from input.html and result.html and consist of DOM-operations and function calls to other JavaScript files.

 

(function(MYSAP, $, undefined) {          MYSAP.submitPerson = function(){                    // Read data from DOM                    var firstName = $('#input_firstname').val();                    var lastName  = $('#input_lastname').val();                    var age                = $('#input_age').val();                    // Create new object                    var person = new MYSAP.Person(firstName, lastName, age);                    // Call instance method                    person.log();                    // Write to SessionStorage                    MYSAP.SessionManager.setPerson('person', person);          };          MYSAP.readPerson = function(){                    // Read person from SessionStorage                    var person = MYSAP.SessionManager.getPerson('person');                    // If person is not null...                    if(person){                              // Call instance method                              person.log();                              // Write data to DOM                              $('#input_firstname').html(person.firstName);                              $('#input_lastname').html(person.lastName);                              $('#input_age').html(person.age);                     }else{                              // Show warning                              $('.alert-block').show();                    }          }           MYSAP.clearPerson = function(){                    // Clear person from SessionStorage                    MYSAP.SessionManager.clearPerson();                    // Reload current location                    location.reload();          } 

}(window.MYSAP = window.MYSAP || {}, jQuery));

 

3.2 person.js

 

In person.js i defined a simple model with a function constructor and an exemplary instance method. An object of this prototype represents our session object, which will be stored in HTML5 Session Storage.

 

(function(MYSAP, $, undefined) {          // Constructor          MYSAP.Person = function(firstName, lastName, age){                    this.firstName = firstName;                    this.lastName  = lastName;                    this.age             = age;          };          MYSAP.Person.constructor = MYSAP.Person;          // Sample instance method          MYSAP.Person.prototype.log = function(){                    console.log(this.firstName + ' ' + this.lastName + ', ' + this.age + ' years');          }; 

}(window.MYSAP = window.MYSAP || {}, jQuery));

 

3.3 sessionmanager.js

 

In sessionmanager.js you can see the logic for accessing Session Storage and serialization/deserialization.

 

( function(MYSAP, $, undefined) {          MYSAP.SessionManager = function() {};          MYSAP.SessionManager.getPerson = function(key) {                    var person;                    // Get item over SessionStorage API                    var person_storage = sessionStorage.getItem(key);                    if (person_storage) {                              // Parse JSON to object                              person_storage = JSON.parse(person_storage);                              // Create new object                              person = new MYSAP.Person(person_storage.firstName, person_storage.lastName, person_storage.age);                    }                    return person;          };          MYSAP.SessionManager.setPerson = function(key, person) {                    if (person) {                              // Serialize Object to JSON                              var person_storage = JSON.stringify(person);                              // Set item over SessionStorage API                              sessionStorage.setItem(key, person_storage);                    }          };          MYSAP.SessionManager.clearPerson = function() {                    sessionStorage.removeItem('person');          }
}(window.MYSAP = window.MYSAP || {}, jQuery));

 

 

4. The App

 

If you submit the first form, all data will be stored into Session Storage. On the next site, data will be read from Session Storage and displayed. When you now switch between both sites, you will see that the result.html will always show the saved data, as long as you don't close your browser or tab.

 

I wanted to show you with this post, how simple it is to create a web-application with client-side session context. You always will need a session handling concept like this, if you don't create a single-page app.

 

And now, please enjoy!

"Add to Home screen" bubble for SAPUI5 mobile apps

$
0
0

Every iOS user should know he can add every mobile optimized website from Safari to the Home screen : the website can be launched from the homescreen like all other native apps without opening Safari.

Moreover we can specify  an icon for the web application used to represent it when added to the Home screen :

 

<link rel="apple-touch-icon" href="/custom_icon.png"/>

 

In my example I want to specify several icons depeding on the device and the screen resolution (iPhone , iPad , iPhone with retina ,iPad with retina, ...)

 

    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">    <link rel="apple-touch-icon" sizes="144x144" href="images/apple-touch-icon-144x144.png">

 

apple-touch-icon.pngapple-touch-icon-72x72.pngapple-touch-icon-114x114.pngapple-touch-icon-144x144.png

 

the official Apple documentation about Specifying a Webpage Icon can be checked here

 


How we can help SAPUI5 mobile users to discover this cool iOS feature?

they will be able to tap our SAPUI5 mobile apps directly from the Home Screen device with a native feeling and the Safari url bar hidden by default.

 

There's nothing too much complicated:using javascript and css we can prompt the user with a custom bubble with the help of an external js library.

The best I found is Add To Home Screen by Qubiq http://cubiq.org/add-to-home-screen

 

Exploring the javascript code and reading the documentation ,  many options are available for a custom optimization such as returningVisitor,custom text message,animationIn,animationOut,etc:

addtohome.JPG

 

in my example I changed default text message with a custom text "This is a SAPUI5 mobile App ..."

 

<link rel="stylesheet" href="css/add2home.css">    <script>    var addToHomeConfig = {            message: 'This is a SAPUI5 mobile App on your %device: tap %icon and then <strong>Add to Home Screen</strong>'        };    </script>    <script type="text/javascript" src="js/add2home.js" charset="utf-8"></script>

 

 

For all available options and complete documentation check the LINK  or  github project

 

Just for my test purpose I'm going to deploy the sapui5 mobile 'hello world' application (from the offical documentation https://sapui5.hana.ondemand.com/sdk/docs/guide/HelloWorld.1.html ) to my Sap Hana Cloud trial account : in this way I'll get a public url to open from my iPhone Safari.

 

My SAPUI5AddToHomeScreen Project looks like this :

eclipseProject.JPG

 

The only changes  in my index.html are the "cool Sap Fiori" blue crystal theme,  custom icons and, of course, the "add to home screen" plugin ( javascript and css )

 

<!DOCTYPE HTML><html>  <head>    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>    <title>Add to Home Screen Example</title>    <script src="resources/sap-ui-core.js"         id="sap-ui-bootstrap"        data-sap-ui-libs="sap.m"         data-sap-ui-theme="sap_bluecrystal">    </script>    <meta name="apple-mobile-web-app-capable" content="yes">    <meta name="apple-mobile-web-app-status-bar-style" content="black">    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">    <link rel="apple-touch-icon" sizes="144x144" href="images/apple-touch-icon-144x144.png">    <link rel="stylesheet" href="css/add2home.css">    <script>    var addToHomeConfig = {            message: 'This is a SAPUI5 mobile App on your %device: tap %icon and then <strong>Add to Home Screen</strong>'        };    </script>    <script type="text/javascript" src="js/add2home.js" charset="utf-8"></script>    <script>      // create a mobile App      // it initializes the HTML page for mobile use and provides animated page handling      var app = new sap.m.App("myApp", {initialPage:"page1"}); // page1 should be displayed first      // create the first page of your application      var page1 = new sap.m.Page("page1", {          title: "Initial Page",          content : new sap.m.Button({   // content is just one Button              text : "Go to Page 2",              tap : function() {                  app.to("page2");   // when tapped, it triggers drilldown to page 2              }          })                      });      // create the second page of your application      var page2 = new sap.m.Page("page2", {          title: "Page 2",          showNavButton: true,       // page 2 should display a back button          navButtonTap: function(){               app.back();            // when tapped, the back button should navigate back up to page 1          },          icon: "http://www.sap.com/global/ui/images/global/sap-logo.png",          content : new sap.m.Text({text:"Hello Mobile World!"})      });      app.addPage(page1).addPage(page2); // add both pages to the App      app.placeAt("content"); // place the App into the HTML document    </script>  </head>  <body class="sapUiBody">    <div id="content"></div>  </body></html>

 

 

 

OFF TOPIC: if you are interest how to get your free trial license and deploy your first Hello World to Sap Hana Cloud trial check the link http://scn.sap.com/docs/DOC-28197


The deployment was Ok...now I have my public url ,open Safari and...let's try it!

Foto 30-07-13 11 51 56.jpgFoto 30-07-13 12 00 43.jpg

Photo 30-07-13 14 32 11.jpgFoto 30-07-13 12 01 50.jpg

Foto 30-07-13 12 02 43.jpg

Creating SAPUI5 Applications based on Public JSON APIs or Web Services

$
0
0

Introduction -

 

For long time I was thinking to build SAPUI5 application based on JSON data. Lots of websites hosts web services or APIs to provide the useful data in the form of JSON format.


Below are the few websites which are exposing the data in the form of JSON APIs.

 

Website
JSON API / Web Service Documentation link
API / Access Key, OAuth Required
Open Weather Map

http://api.openweathermap.org/API

No Access Key Required
Weather Under Ground

http://api.wunderground.com/weather/api/d/docs

API Key Required
Rotten Tomatoes

http://developer.rottentomatoes.com/docs/read/JSON

API Key Required
GeoNames

http://www.geonames.org/export/ws-overview.html

API Key Required
Facebook

http://developers.facebook.com/docs/reference/api/search/

API Key Required, OAuth Access Required
Twitter

https://dev.twitter.com/docs/api/1.1/overview

API Key Required, OAuth Access Required

You Tube

https://developers.google.com/youtube/2.0/developers_guide_json

API Key Required, OAuth Access Required

LinkedIn

http://developer.linkedin.com/documents/api-requests-json

API Key Required, OAuth Access Required

Google Maps

https://developers.google.com/maps/documentation/webservices/

No Access Key Required

 

 

There are lots of blog available which explains how to consume and build SAPUI5 application based on OData but not much information is available on consuming JSON data and hence I thought to write this blog.


By consuming easily available JSON data, we can develop “n” number of mashup web applications. It could be hybrid applications based on public JSON data along with SAP business suite data!


Another advantage I found with this approach is, it makes learning SAPUI5 very easy as you need not to depend on any SAP system for data, access etc. you can get pretty neat data to be consumed in your application and you can play around with that data  by experimenting various UI controls.


In this blog, I will walk you through 4 SAPUI5 applications developed by me and based on JSON APIs.


  • SAPUI5 Application based on Weather Underground JSON API
  • SAPUI5 Application based on GeoNames wikipediaSearch JSON API
  • SAPUI5 Application based on Rotten Tomatoes JSON API
  • SAPUI5 Application based on Open Weather Map JSON API

 


Let’s get into details of each application

 

     1. SAPUI5 Application based on Weather Underground JSON API


For this application, I used below JSON API Service URL.


http://api.wunderground.com/api/Your_Key/conditions/forecast/q/autoip.json


To use these APIs, you need to first sign up and get your API key.


This API basically detects your location based on IP address and gets the weather information for your current location. You can still use other APIs to which you need to provide query parameters as per API documentation.


Very important point is you cannot directly access the URL in your SAPUI5 application because you will be making call in the cross domain environment and you may get below kind of errors.


Origin http://localhost:54788 is not allowed by Access-Control-Allow-Origin.

 

XMLHttpRequest cannot load http://api.example.com/api/xyz.json. Origin http://localhost:54788 is not allowed by Access-Control-Allow-Origin.


To make call without any error, we need to use cross domain Ajax request. Very well explanation on how to do it can be found in blog http://scn.sap.com/community/developer-center/front-end/blog/2013/06/14/useful-jquery-functions-for-sapui5-development

 

Also you can refer http://scn.sap.com/community/developer-center/front-end/blog/2013/07/15/secret-behind-jsonp

 

Once you get the JSON data successfully, the next important step is to set this data to JSONModel.


Finally you need to understand data model of JSON format and how you will be able to read it, loop it etc.


You can refer SAPUI5 documentation at below link which very well explains the methods available to manipulate JSON data. https://sapui5.hana.ondemand.com/sdk/#docs/api/symbols/sap.ui.model.json.JSONModel.html

 

The best approach to see the structure of JSON data is to use online JSON viewer tools. One of the best tools I am using is available athttp://jsonviewer.stack.hu/

 

Here you need to load JSON raw data by providing direct URL

ui5_json1.jpg

Once the data is loaded, it will be displayed in raw format.

ui5_json2.jpg


By clicking on Viewer, it will display JSON data into tree format with name/value pair, deep array, nested objects etc.

ui5_json3.jpg

Let's see the complete code of the application


<!DOCTYPE html><html><head><!-- Added charset='utf-8' to handle data in various langauges --><meta http-equiv='X-UA-Compatible' content='IE=edge' charset='utf-8' /><title>Weather Forecast</title><!-- Load UI5, select gold reflection theme and the "commons" and "table" control libraries --><script id='sap-ui-bootstrap' type='text/javascript'          src='resources/sap-ui-core.js' data-sap-ui-theme='sap_platinum'          data-sap-ui-libs='sap.ui.commons,sap.ui.table'></script><script type="text/javascript">     // create a JSONModel, fill in the data and bind the Table to this model            var oModel = new sap.ui.model.json.JSONModel();          // service url for Weather Underground JSON API             var url = 'http://api.wunderground.com/api/Your_Key/conditions/forecast/q/autoip.json?callback=getJSON';          // var url = 'http://api.wunderground.com/api/Your_Key/conditions/forecast/lang:MR/q/autoip.json?callback=getJSON';  //Example URL          // var url = 'http://api.wunderground.com/api/Your_Key/forecast/conditions/lang:MR/q/France/Paris.json?callback=getJSON';   //Example URL          //Ajax Call with Callback function and JSONP data type             $                              .ajax({                                        url : url,                                        jsonpCallback : 'getJSON',                                        contentType : "application/json",                                        dataType : 'jsonp',                                        success : function(data, textStatus, jqXHR) {                                                  oModel.setData(data);                                                  sap.ui.getCore().setModel(oModel);                                                  // create matrix layout                                                    var oMatrix = new sap.ui.commons.layout.MatrixLayout({                                                            id : 'matrix',                                                            layoutFixed : false,                                                            columns : 3,                                                  });                                                  var oCell = new sap.ui.commons.layout.MatrixLayoutCell({                                                            colSpan : 3                                                  });                                                  var oTV = new sap.ui.commons.TextView(                                                                      {                                                                                id : 'TV-Head',                                                                                text : 'SAPUI5 Application based on Weather Underground JSON API',                                                                                design : sap.ui.commons.TextViewDesign.H1                                                                      });                                                  oCell.addContent(oTV);                                                  oMatrix.createRow(oCell);                                                  //Create a standard divider                                                    var oCell = new sap.ui.commons.layout.MatrixLayoutCell({                                                            colSpan : 3                                                  });                                                  oCell.addContent(new sap.ui.commons.HorizontalDivider());                                                  oMatrix.createRow(oCell);                                                  //Lable and TextField for City                                                    oLabelCity = new sap.ui.commons.Label({                                                            id : 'L-City',                                                            text : 'City'                                                  });                                                  oTFCity = new sap.ui.commons.TextField({                                                            id : 'TF-City',                                                            tooltip : 'City',                                                            editable : false,                                                            value : '{/current_observation/display_location/full}',                                                            width : '200px'                                                  });                                                  oLabelCity.setLabelFor(oTFCity);                                                  oMatrix.createRow(oLabelCity, oTFCity);                                                  //Lable and TextField for Latitute                                                    oLabelLat = new sap.ui.commons.Label({                                                            id : 'L-Lat',                                                            text : 'Latitude'                                                  });                                                  oTFLat = new sap.ui.commons.TextField(                                                                      {                                                                                id : 'TF-Lat',                                                                                tooltip : 'Latitude',                                                                                editable : false,                                                                                value : '{/current_observation/display_location/latitude}',                                                                                width : '200px'                                                                      });                                                  oLabelLat.setLabelFor(oTFLat);                                                  oMatrix.createRow(oLabelLat, oTFLat);                                                  //Lable and TextField for longitude                                                    oLabelLon = new sap.ui.commons.Label({                                                            id : 'L-Lon',                                                            text : 'Longitude'                                                  });                                                  oTFLon = new sap.ui.commons.TextField(                                                                      {                                                                                id : 'TF-Lon',                                                                                tooltip : 'Longitude',                                                                                editable : false,                                                                                value : '{/current_observation/display_location/longitude}',                                                                                width : '200px'                                                                      });                                                  oLabelLon.setLabelFor(oTFLon);                                                  oMatrix.createRow(oLabelLon, oTFLon);                                                  //Lable and TextField for Elevation                                                    oLabelElev = new sap.ui.commons.Label({                                                            id : 'L-Elev',                                                            text : 'Elevation'                                                  });                                                  oTFElev = new sap.ui.commons.TextField(                                                                      {                                                                                id : 'TF-Elev',                                                                                tooltip : 'Elevation',                                                                                editable : false,                                                                                value : '{/current_observation/observation_location/elevation}',                                                                                width : '200px'                                                                      });                                                  oLabelElev.setLabelFor(oTFElev);                                                  oMatrix.createRow(oLabelElev, oTFElev);                                                  //Create a standard divider                                                    var oCell = new sap.ui.commons.layout.MatrixLayoutCell({                                                            colSpan : 3                                                  });                                                  oCell.addContent(new sap.ui.commons.HorizontalDivider());                                                  oMatrix.createRow(oCell);                                                  //Weather image                                                    var oImageWeather = new sap.ui.commons.Image({                                                            src : '{/current_observation/icon_url}',                                                            alt : '{/current_observation/icon}'                                                  });                                                  //Lable and TextField for weather                                                    oLabelWeather = new sap.ui.commons.Label({                                                            id : 'L-Weather',                                                            text : 'Weather'                                                  });                                                  oTFWeather = new sap.ui.commons.TextField({                                                            id : 'TF-Weather',                                                            tooltip : 'Weather',                                                            editable : false,                                                            value : '{/current_observation/weather}',                                                            width : '200px'                                                  });                                                  oLabelWeather.setLabelFor(oTFWeather);                                                  oMatrix.createRow(oLabelWeather, oTFWeather, oImageWeather);                                                  //Create a standard divider                                                    var oCell = new sap.ui.commons.layout.MatrixLayoutCell({                                                            colSpan : 3                                                  });                                                  oCell.addContent(new sap.ui.commons.HorizontalDivider());                                                  oMatrix.createRow(oCell);                                                  //Lable and TextField for temp_c                                                    oLabelTemp = new sap.ui.commons.Label({                                                            id : 'L-Temp',                                                            text : 'Temperature'                                                  });                                                  var tempstring = oModel                                                                      .getProperty("/current_observation/temp_c");                                                  //Append Degree Celsius unit symbol to Temperature reading                                                     var tempinC = tempstring + "\u2103";                                                  oTFTemp = new sap.ui.commons.TextField({                                                            id : 'TF-Temp',                                                            tooltip : 'Temperature',                                                            editable : false,                                                            value : tempinC,                                                            width : '220px'                                                  });                                                  oLabelTemp.setLabelFor(oTFTemp);                                                  oMatrix.createRow(oLabelTemp, oTFTemp);                                                  //Lable and TextField for Obervation Time                                                    oLabelObsTime = new sap.ui.commons.Label({                                                            id : 'L-ObsTime',                                                            text : 'Observation Time'                                                  });                                                  oTFObsTime = new sap.ui.commons.TextField({                                                            id : 'TF-ObsTime',                                                            tooltip : 'Observation Time',                                                            editable : false,                                                            value : '{/current_observation/observation_time}',                                                            width : '220px'                                                  });                                                  oLabelObsTime.setLabelFor(oTFObsTime);                                                  oMatrix.createRow(oLabelObsTime, oTFObsTime);                                                  //Lable and TextField for Local Time                                                    oLabelLclTime = new sap.ui.commons.Label({                                                            id : 'L-LclTime',                                                            text : 'Local Time'                                                  });                                                  oTFLclTime = new sap.ui.commons.TextField({                                                            id : 'TF-LclTime',                                                            tooltip : 'Local Time',                                                            editable : false,                                                            value : '{/current_observation/local_time_rfc822}',                                                            width : '220px'                                                  });                                                  oLabelLclTime.setLabelFor(oTFLclTime);                                                  oMatrix.createRow(oLabelLclTime, oTFLclTime);                                                  //Lable and TextField for relative humidity                                                    oLabelRelHum = new sap.ui.commons.Label({                                                            id : 'L-RelHum',                                                            text : 'Relative Humidity'                                                  });                                                  oTFRelHum = new sap.ui.commons.TextField({                                                            id : 'TF-RelHum',                                                            tooltip : 'Relative Humidity',                                                            editable : false,                                                            value : '{/current_observation/relative_humidity}',                                                            width : '220px'                                                  });                                                  oLabelRelHum.setLabelFor(oTFRelHum);                                                  oMatrix.createRow(oLabelRelHum, oTFRelHum);                                                  //Lable and TextField for Wind                                                    oLabelWind = new sap.ui.commons.Label({                                                            id : 'L-Wind',                                                            text : 'Wind'                                                  });                                                  oTFWind = new sap.ui.commons.TextField({                                                            id : 'TF-Wind',                                                            tooltip : 'Wind',                                                            editable : false,                                                            value : '{/current_observation/wind_string}',                                                            width : '220px'                                                  });                                                  oLabelWind.setLabelFor(oTFWind);                                                  oMatrix.createRow(oLabelWind, oTFWind);                                                  //attach it to some element in the page                                                    oMatrix.placeAt('content');                                                  //Create an instance of the table control                                                    var oTable1 = new sap.ui.table.Table({                                                            title : "Simple Forecast Details",                                                            visibleRowCount : 4,                                                            selectionMode : sap.ui.table.SelectionMode.Single,                                                            navigationMode : sap.ui.table.NavigationMode.Paginator,                                                  });                                                  //Define the columns and the control templates to be used                                                    oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Period"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "date/weekday"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Image"                                                            }),                                                            template : new sap.ui.commons.Image().bindProperty(                                                                                "src", "icon_url"),                                                            width : "10px",                                                            hAlign : "Center"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "High"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "high/celsius"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Low"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "low/celsius"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Avarage Humidity"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "avehumidity"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Max Humidity"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "maxhumidity"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Min Humidity"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "minhumidity"),                                                            width : "10px"                                                  }));                                                  oTable1.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Chance of Precipitation"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "pop"),                                                            width : "10px"                                                  }));                                                  //Create a model and bind the table rows to this model                                                    var oModel2 = new sap.ui.model.json.JSONModel();                                                  //Get he forecastday array from simpleforecast object                                                    var aSimpleForecast = oModel.getProperty("/forecast/simpleforecast/forecastday");                                                  oModel2.setData({                                                            modelData : aSimpleForecast                                                  });                                                  oTable1.setModel(oModel2);                                                  oTable1.bindRows("/modelData");                                                  oTable1.placeAt('content');                                                  //Create an instance of the table control                                                    var oTable = new sap.ui.table.Table({                                                            title : "Textual Forecast Details",                                                            visibleRowCount : 8,                                                            selectionMode : sap.ui.table.SelectionMode.Single,                                                            navigationMode : sap.ui.table.NavigationMode.Paginator,                                                  });                                                  //Define the columns and the control templates to be used                                                    oTable.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Period"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "title"),                                                            width : "50px"                                                  }));                                                  oTable.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Image"                                                            }),                                                            template : new sap.ui.commons.Image().bindProperty(                                                                                "src", "icon_url"),                                                            width : "75px",                                                            hAlign : "Center"                                                  }));                                                  oTable.addColumn(new sap.ui.table.Column({                                                            label : new sap.ui.commons.Label({                                                                      text : "Forecast"                                                            }),                                                            template : new sap.ui.commons.TextView().bindProperty(                                                                                "text", "fcttext_metric"),                                                            width : "300px"                                                  }));                                                  //Create a model and bind the table rows to this model                                                    var oModel1 = new sap.ui.model.json.JSONModel();                                                  //Get the forecastday array table from txt_forecast object                                                    var aData = oModel.getProperty("/forecast/txt_forecast/forecastday");                                                  oModel1.setData({                                                            modelData : aData                                                  });                                                  oTable.setModel(oModel1);                                                  oTable.bindRows("/modelData");                                                  oTable.placeAt('content');                                        }                              });</script></head><body class='sapUiBody'>          <div id='content'></div>          <p></p>          <div id="footer">                    <div style="float: right; text-align: right;">                              <img src="http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png"                                        border="0" alt=""><br> <span style="padding-top: 20px;">Weather          data provided by Weather Underground, Inc.</span>                    </div>          </div></body></html>


Now let me show you the output screen after running SAPUI5 application. Based on geolocation determined by IP address, it will display weather information.

 

Yes currently its rainy season here in Pune!

ui5_json4.jpg

ui5_json5.jpg

I created view with few textfields and two table UI controls. After getting data from JSON API, I am mapping these fields to textfields and tables.


Let’s understand the code in detail,


Below code makes Ajax call with datatype as JSONP to external JSON APIs. JSON data will be then set to oModel using setData method.


// create a JSONModel, fill in the data and bind the Table to this model 

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

 

// service url for Weather Underground JSON API  

var url = 'http://api.wunderground.com/api/Your_Key/conditions/forecast/q/autoip.json?callback=getJSON';

 

       //Ajax Call with Callback function and JSONP data type       

       $

                     .ajax({

                           url : url,

                           jsonpCallback : 'getJSON',

                           contentType : "application/json",

                           dataType : 'jsonp',

                           success : function(data, textStatus, jqXHR) {

 

                                  oModel.setData(data);

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

});

 

 

To set this data to various UI controls, we need to access value of the required JSON object by providing its access path.

For e.g. we want to display city name.  As per JSON viewer, city full name can be accessed from path current_observation-->display_location-->full 

ui5_json6.jpg

And on similar lines, to set the value to UI control we need to use {/current_observation/display_location/full}

 

//Lable and TextField for City 

                                  oLabelCity = new sap.ui.commons.Label({

                                         id : 'L-City',

                                         text : 'City'

                                  });

 

                                  oTFCity = new sap.ui.commons.TextField({

                                         id : 'TF-City',

                                         tooltip : 'City',

                                         editable : false,

                                         value : '{/current_observation/display_location/full}',

                                         width : '200px'

                                  });

                                  oLabelCity.setLabelFor(oTFCity);

                                  oMatrix.createRow(oLabelCity, oTFCity);

 

If we want to manipulate data before setting it to UI control, we need to get the value using method getProperty of JSON model.

In the application, we want to display temperature with ºC symbol. For that purpose, first we need to get the temperature value and then append symbol to it.

 

var tempstring = oModel.getProperty("/current_observation/temp_c");

 

//Append Degree Celsius unit symbol to Temperature reading  

                                  var tempinC = tempstring + "\u2103";

 

 

 

The next important piece of code is to display nested array data into table UI control.

 

In the example application, we are displaying 2 tables with weather information. One of the tables contains Textual Forecast details which is accessible as forecast-->txt_forecast-->forecastday. Here forecastday is the array of objects which we want to display as table data.

ui5_json7.jpg

As mentioned in below code, we need to first get the access using getProperty method and then by setting it to new JSON model using method setData, we can directly bind the array to the table as model.

 

//Create a model and bind the table rows to this model 

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

 

//Get the forecastday array table from txt_forecast object 

var aData = oModel.getProperty("/forecast/txt_forecast/forecastday");

 

                                  oModel1.setData({

                                         modelData : aData

                                  });

 

                                  oTable.setModel(oModel1);

                                  oTable.bindRows("/modelData");

                                  oTable.placeAt('content');

 

 

And then column values will be simply provided as usual. Here image property srs is set to “icon_url” which is one of the fields of forecastday array

 

                                  oTable.addColumn(new sap.ui.table.Column({

                                         label : new sap.ui.commons.Label({

                                                text : "Image"

                                         }),

                                         template : new sap.ui.commons.Image().bindProperty(

                                                       "src", "icon_url"),

                                         width : "75px",

                                         hAlign : "Center"

                                  }));

 

 

One of the real fun with this API is it supports multiple languages. Below is the screenshot of the same application displayed inMarathi language.

 

For that, I supplied URL as var url = 'http: //api.wunderground.com/api/Your_Key/conditions/forecast/lang:MR/q/autoip.json?callback=getJSON';

ui5_json8.jpg

ui5_json9.jpg

To display text in different languages, we need to change the page encoding toUTF-8   

 

For this purpose, I added below code.

 

<!-- Added charset='utf-8' to handle data in various langauges -->

<metahttp-equiv='X-UA-Compatible'content='IE=edge'charset='utf-8'/>


P.S – even after setting page encoding, if you execute application by web preview in eclipse, you will not see correct output. But it works perfectly fine in Google’s chrome browser.

 

     2. SAPUI5 Application based on GeoNames wikipediaSearch JSON API

 

Let’s see UI of the 2nd application.

ui5_json10.jpg

ui5_json11.jpg

This application basically takes 2 parameters as input. Query string and max number of rows which are then passed to JSON service url as,

 

//GeoNames WikipediaSearch JSON API service URL

                                  var url = 'http://api.geonames.org/wikipediaSearchJSON?formatted=true&q='

                                                + qString

                                                + '&maxRows='

                                                + maxRow

                                                + '&username=<Your_User_Name> &style=full';

 

 

     3. SAPUI5 Application based on Rotten Tomatoes JSON API


Third application is based on Rotten Tomatoes JSON API which basically provides movie related data.

 

UI of this application is as below,

ui5_json12.jpg

 

I am providing option to select different type of movies and DVDs along with number of movies to be returned. These values then mapped to URL parameter as below,

// Rotten Tomatoes API's JSON service url 

                     var url = 'http://api.rottentomatoes.com/api/public/v1.0/lists/'

                                  + ddKey + '/' + ddValue

                                  + '.json?apikey=<your_api_key> &limit='

+ maxRow

                                  + '&callback=getJSON';

Here I am getting current box office movies and returning just one movie. On row selection, I am displaying the cast of the movie.

ui5_json13.jpg

Here I am querying upcoming movies. By default, it will return 10 movies as per API documentation.

ui5_json14.jpg

Here I am getting In Theaters movies. Based on value selected, I am setting the table title.

ui5_json15.jpg

 

Please pay attention on how row selection event is handled and how 2nd table for cast of the movie got displayed. Source code can be accessed at https://github.com/CmIm/sap-ui5


     4. SAPUI5 Application based on Open Weather Map JSON API

 

This last application is based on open weather map API and this do not required any API key or registration to web service. Below is the UI for this application,

ui5_json16.jpg

I am getting city name and passing it to JSON URL as below,

 

// service url for Open Weather Map JSON API

                                  var url = 'http://api.openweathermap.org/data/2.5/weather?q='+ qString + '&mode=json&units=metric&callback=getJSON';

 

 

Let’s see how the current weather of Walldorf, Germany looks like,

ui5_json17.jpg

You can access the source code for all these applications at https://github.com/CmIm/sap-ui5

 

 

 

Closing Remarks –

 

This is just an attempt to share information on how we can consume JSON public APIs. I thought to develop SAPUI5 application which will access twitter, Facebook data but for that it requires access token with OAuth on which I do not have sufficient knowledge. May be some of you can try those things.


Personally the key benefit out of these things is my learning curve towards SAPUI5 significantly improved as I am experimenting various UI controls, methods on easily available JSON data. It is like getting self-assignments by looking at data and thinking different UI design, how I can utilize various UI controls etc.

 

The more complex JSON model, more it will be challenging to try out different UI designs and how we can make it look more better and better!


Now I am thinking why can’t we have SAPUI5 challenge on similar lines of Data Geek challenge? Here we can try out various SAPUI5 applications based on public JSON APIs. What do you guys say about this


Happy Learning and Coding!


Authentication with SAP Backend for SAPUI5 Hybrid Phonegap apps

$
0
0

From experience I know that a lot of developers struggle when they try to set up authentication to a SAP back end from a Phonegap application.  The reason for this is that there are some big differences between a local app on a device and using a browser where you have standard SAP authentication mechanisms such as the basic authentication popup from the ICF framework or enterprise portal and NWBC logon functionality.

 

I will walk you through the basics of a solution which I find to be effective with SAPUI5 apps. Even though this was originally created for Neptune apps I believe it should be reusable for oData gateway based apps as well. I will also share a SMP Cloud version with onboarding functionality when that is ready and I’ll try to convince SAP Mentor Roel van den Berge to try it out with Fiori as well

 

Here is the javascript https://github.com/nstabell/NeptuneSoftware/blob/master/sapui5_netweaver_logon.js that includes all the code you need for a basic logon to a Netweaver system (Note that there are some Neptune specific responses here to detect password change events etc. Remove thos if you do not use Neptune)

 

In a SAPUI5 Phonegap app all your HTML, css and javascript resources are stored locally on your device. Communication with the backend is performed through HTTPS (You should never use HTTP in a productive solution for obvious security reasons) and in this example by jQuery ajax calls with json data.

When we communicate with the SAP ICF framework the server will respond with different HTTP response status codes. (For a list see this List of HTTP status codes - Wikipedia, the free encyclopedia )

 

The one we focus on here is the 401 unauthorized code that tells our ajax call that the user is unauthorized. In the script we globally intercept any ajaxerror and call a function that prompts for user credentials if SAP requires authentication.

 

To catch an ajax error we use the following code:

 

// Global Ajax Error
$(document).ajaxError(function(event, request, settings)

 

And from the request we get the status and can use a switch to check for the cases.

switch (request.status)

For 401 we will pop the logon dialog that prompt for username and password:

 

  case 401:    UI5Logon();    break;

 

The UI5Logon function:

function UI5Logon() {     oLogonDialog.open();
}

 

We want to store the credentials in a session storage and update the HTTP request header with the Basic Auth information when the user has entered his credentials

 

function UI5LogonPutLS() {

// Build Auth String
var tok  = inUserName.getValue() + ':' + inPassword.getValue();
var hash = Base64.encode(tok);
var auth = "Basic " + hash;

// Save to Local Storage
$.sap.require("jquery.sap.storage");
var UI5Storage = $.sap.storage(jQuery.sap.storage.Type.session);
UI5Storage.remove("Auth");
UI5Storage.put("Auth",auth);
}

 

There are some more functionality such as base64 encoding in the script but you can read that from the code.

Add the file in your phonegap zip (for the Adobe build service) and add a reference in the header of your html files

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

 

1.png

 

Run the app and you should get a Dialog popup when you receive a 401 response:

 

2.PNG

 

And when authenticated you receive data from the backend

 

3.PNG

 

This was just a mockup app  and if you wish to create a nice SAPUI5 app (based on Neptune) you can have a look at this blog

 

Here is an example of an HR app template to show the possibilities with SAPUI5:

 

For Desktop

For Mobile browser

 

 

Happy SAPUI5 coding


Web Developers – Gear Up Weapons

$
0
0

In my perspective developing an application on web is similar to entering a war zone. As a soldier, he/she requires right weapons and tactics to survive in the war zone similarly a web developer also requires the right web development tools and knowledge to survive in the browser war zone.

Everyone knows it really a daunting to task to provide aesthetic view and appealing feel to user. Web developers indeed have to cross various hurdles in order to at least get close to achieving the target set by customer. In my opinion getting ready with right tools would be the first and foremost hurdle to cross. Let me share across the Chrome/Firefox Development tools which would make your life easier. Let the countdown begin

1.Web Developer

Web Developer is a Firefox/Chrome extension which adds a large collection of development tools to your browser. The integrated menu and toolbar contain dozens of useful features for both developers and designers alike.

web-developer

Chrome Store: : Visit Store

Mozilla Addon : Visit Addon

2.Firebug

Firebug is a web development tool which allows the developers to inspect HTML and modify style and layout in real-time, use the most advanced JavaScript debugger available for any browser, accurately analyze network usage and performance and many more. If you are using Chrome you can go ahead use there prebuilt developer tools as an alternate option to firebug.

If you are using Chrome Browser my personal choice would be to go with default chrome developer tools as it comes with equivalent or more features than firebug.

firebug

Chrome Store: : Visit Store

Mozilla Addon : Visit Addon

3.MeasureIT

Draw a ruler across any webpage to check the width, height, or alignment of page elements in pixels. Web developer also comes up with ruler but I prefer MeasureIt, it’s all left up to you to choose your preferred choice.

measureit

Chrome Store: : Visit Store

Mozilla Addon : Visit Addon

4.Live Edit

Edit any page live on the go while you are browsing. To get back to the original state simply refresh the page. Another option of editing any page on live would be Tincr Extension.

live-edit

Chrome Store: : Visit Store

Mozilla Addon : Visit Addon

5.Color Zilla

With ColorZilla you can get a color reading from any point in your browser, quickly adjust this color and paste it into another program. You can Zoom the page you are viewing and measure distances between any two points on the page. The built-in palette browser allows choosing colors from pre-defined color sets and saving the most used colors in custom palettes. DOM spying features allow getting various information about DOM elements quickly and easily. The powerful CSS gradient generator allows quick and easy creation of beautiful gradients.

colorzilla-for-chrome

Chrome Store: : Visit Store

Mozilla Addon : Visit Addon

6.Texter

Text substitution app Texter saves you countless keystrokes by replacing abbreviations with commonly used phrases you define.

Unlike software-specific text replacement features, Texter runs in the Windows system tray and works in any application you’re typing in. Texter can also set return-to markers for your cursor and insert clipboard contents into your replacement text, in addition to more advanced keyboard macros. Texter really saves a lot of time while coding with ignoring retyping the whole code phrase which is repeated several times.

texter

Download Link: : Visit Site

Final Words:

Hope these tools helps you in your development process. Happy Coding :)

Understanding Closures in UI5 Javascript

$
0
0

The concept of "Closures" is one of the very few things that are unanimously considered to be "tricky" in the Javascript community. It is especially challenging for people who are new to Javascript. It is also one of the few things for which a mere Google search is not enough to get a gist of.

And get this - As a UI5 Javascript developer, you are most likely already taking advantage of the power of Closures without even realizing it!

 

So what's the big deal? What makes it such an elusive concept? Why doesn't someone define it clearly? Let's begin by having a look at what happened when someone did try to define it clearly...

"A closure in Javascript is a function or reference to a function together with a referencing environment. A closure allows a function to access those non-local variables even when invoked outside of its immediate lexical scope." - Wikipedia

what.jpg

 

Okay. While the definition is indeed technically correct, it's certainly not going to help us understand what Closures are. So let us loosen up a bit with the definitions-kind-of-techy-geeky-language and try to understand what a closure is in simpler language. Ready?

 

The rest of the post is split into 2 sections :

  1. Bare bones definition
  2. A more practical UI5 example

 

 

1. Bare bones definition

 

Created a function within a function? You've created a Closure!

Let's see a small example of a function defined within another function. It will also help us understand what "referencing environment" in the technical definition means.

 

//This is our outer function
function showMySecret(password) {     var secretAnswer = 42;     var prefix = "The secret is ";     function showSecret() {          alert(prefix + secretAnswer);     }     //Call our inner function if password is correct     if(password === "Pass123") {          showSecret();     }
}

 

The "referencing environment" can be understood as a table of name-value pairs that defines the 'environment' or 'context' in which the inner function will run. It is a snapshot of the values of the variables declared within the outer function, that can possibly affect the behaviour of the inner function. The referencing environment consists of...

  1. Formal parameters of the outer function (password)
  2. Variables that are declared within the outer function (secretAnswer, prefix)

ref_environ.png

This table is created at the time of invocation of the outer function[1] (because the value of the formal parameter wouldn't be known earlier!). So when we invoke our outer function (showMySecret) as follows...

 

showMySecret("Pass123");

 

... the environment snapshot will look like this...

 

environ.png

 

All good so far? Great! So now we know what the inner function and outer function look like. We also know what information our 'snapshot table' contains. So what's a closure?

 

The inner function and the snapshot table together form the closure.

closure.png

 

As we can clearly see, a closure has enough information for the inner function to run, and that too, without depending on the outer function in any way. This is an extremely important point because of the way functions are treated in Javascript. In Javascript, whenever you create a new function, you are actually creating Function objects. And like every other object, Function objects too are eligible to be garbage collected as soon as they have finished executing and are no longer being referenced.

Since our closure contains all the information that the inner function needs to execute, it can be executed even after the outer function is disposed by the garbage collector.

 

Our first example was intentionally kept simple, so that we could easily arrive at an understanding of what a closure is. Due to its simplicity though, it does not exhibit any of the advantages of having a closure. Its true power will become obvious only when the inner function is invoked from outside the outer function. But how is it possible to have a function defined within another function and yet be invoked from outside? Grab a cup of coffee, and get ready for a slightly more interesting example!

 

2. A more practical UI5 example

getbutton.png

 

Our second example (this time in UI5) too is pretty straight-forward. Unlike our first example, this is actually the kind of code that you are likely to come across in productive code. We have a helper method getButton that takes the button text and alert text as parameters, and returns a UI5 button accordingly.

Can you spot the closure here?

 

getbutton.png

 

Here our inner function is an anonymous function[2] that we create and assign as oButton's listener for its 'press' event. Even though the inner function is defined inside the outer function, it is invoked only when the user clicks on the button - making it a good example of the inner function beinginvoked from outside of the outer function. If Javascript didn't have the mysteriously wonderful concept of closures, this code wouldn't work! Since the VM[3] will execute only the inner function (which is the event handler) when the 'press' event occurs, and since sAlertText isn't defined anywhere within the inner function[4], this code would fail to work as intended.

noclosure.png

 

But thankfully, Javascript does have closures, and this code does manage to work perfectly. When the 'press' event handler is executed, the handler (the inner function) first looks for a definition of sAlertText within its own body. When it fails to find anything, before losing all hope, it turns to its 'referencing environment' table and looks for sAlertText. Voila! It finds an entry there, picks up the corresponding value and uses it for the alert() statement. So even though sAlertText is seemingly undefined within the function body, the closure knows it all.

cl.png

 

When you invoke a function that is defined within another function, remember that you're dealing with a closure. It remembers the values of variables defined within its outer function. This might not always be desirable though, because the values in the 'snapshot table' might be considered 'stale' or 'outdated' (depending on the scenario) if the inner function is invoked, say, 1 hour after it is created.

Worry not, however - there are techniques and patterns that help you avoid closures too.

 

 

If you invoke the getButton() 15 times (to create 15 buttons), you do essentially create 15 closures, and each closure will have its own value for sButtonText and sAlertText according to the arguments that you passed while calling getButton() each time.

 

 

[1] : To be more precise, it is created when the inner function is created.

[2] : Anonymous function : Just a fancy name for a function that is defined without a name. In all other aspects, anonymous functions are just like any other function.

[3] : Javascript code is executed within an environment called 'Virtual Machine (VM)'. Every browser comes bundled with a Javascript VM that is used for running the Javascript code that websites contain.

[4] : Assuming that a variable with name sAlertText also doesn't exist in global scope.

 

 

 

3. Conclusion

I told you! You've been using closures without realizing that they even exist, haven't you? However, knowing about them and knowing how they work just might turn out to be crucial in your next debugging-marathon or your next new development. Just sayin'. Also, I really hope are able to take away at least a little learning from this post (Psst. my first blog post!)

Please comment and share your criticism. Did you find it clear enough? Did I miss anything important? Have you had any (painful/pleasant) experiences with closures?

 

Fortunately or unfortunately, this was just the tip of the iceberg. Closures may seem to behave 'awkwardly' when they are created inside a loop. Closures are also central to some very important Javascript design patterns. And have you ever seen a "var that = this;" statement in Javascript code? What the heck is that? What happens when you create a function within another function within yet another function!? And how do you make sure you don't accidentally create closures when you don't need them? All this and other UI5 'How-to's - in my upcoming blog posts! Click on 'Follow' to stay updated!

BSP application names and SICF nodes for SAPUI5 on ABAP server

$
0
0

The SAPUI5 developer guide describes how to deploy a SAPUI5 application project to the SAPUI5 repository on the ABAP server in minute detail (https://sapui5.hana.ondemand.com/sdk/docs/guide/UI5BSPRepository.html). Technically, the files of the SAPUI5 application are stored as a BSP application on the server. You can create a BSP application with the wizard in Eclipse or use an application already existing on the server or create a new one manually on the server. What I miss from the guide are the subtle details around names if you create the BSP application manually. The name of the BSP application as well as the location and the name of the SICF service node must follow some rules.

 

According to the guide, the SAPUI5 application node in SICF has to be created in the branch /sap/bc/ui5_ui5/<namespace>. Usually, the namespace would be sap, which is what it has to be if you use the Eclipse wizard. But you can pick your own namespace as well, if you have one registered in the system. To use a custom namespace, you need to add a node with its name exactly like the namepsace as a child node of /sap/bc/ui5_ui5/. Your applications must then be published as child nodes of your namespace node e.g. /sap/bc/ui5_ui5/iprocon/testui5.

icf branch ui5_ui5.png

The reason for this comes from the logic in the http handler classes for SAPUI5, that are registered with the node /sap/bc/ui5_ui5. The mapping of the URL to the BSP application resources is done inside these classes.

sicf service ui5_ui5 handler list.png

All put together,  if you want to use a custom namespace, then you need to create a child node for ui5_ui5 named as your namespace and add a child node to your namespace node with just the name of your BSP application without namespace prefix. The BSP application name itself nevertheless must contain the namespace prefix:

  • SICF node for the SAPUI5 application in custom namespace: /sap/bc/ui5_ui5/iprocon/testui5
  • BSP application name in custom namespace: /IPROCON/TESTUI5

If you do not want to use a custom namespace, you can simply pick any BSP application name from the customer namespace and create a sicf node with your application name as child of /sap/bc/ui5_ui5/sap.

  • SICF node for the SAPUI5 application: /sap/bc/ui5_ui5/sap/ztestui5
  • BSP application name: ZTESTUI5

Virtual Keyboard integration with SAPUI5 Application!

$
0
0

In this blog, I am going to explain how we can integrate virtual keyboard into SAPUI5 application.

 

As per Wikipedia,

A virtual keyboard is a software component that allows a user to enter characters.A virtual keyboard can usually be operated with multiple input devices, which may include a touchscreen, an actual Computer keyboard and a computer mouse.

 

There are lots of advantages associated with virtual keyboard. Some of these are,

 

  • Users can type with their own language on foreign keyboards
  • Very much useful for disabled users as they can use mouse to type
  • Virtual keyboards may be used in some cases to reduce the risk ofkeystroke logging
  • Users can easily switch between different character sets
  • On Application logon pages, for user id and password fields, we can provide virtual keyboard option to users to increase the security for authenticate users.

 

I was wondering how we can integrate virtual keyboard with SAPUI5 applications as it is one of the important feature considering all above mentioned advantages. While searching on internet, I came across Google API for virtual keyboard. Please refer  https://developers.google.com/virtual-keyboard/

 

Based on this API documentation, I build simple application which looks as below,

 

Here I am using virtual keyboard with Hindi as input language.

ui5_vk1.jpg

 

Below is the screenshot with English language Keyboard.

ui5_vk2.jpg

 

In this demo application, I tried different UI controls which requires User inputs such as TextField, TextArea, PasswordField and Note Taker.

 

Now let's see the code of this demo application.

 

<!DOCTYPE HTML><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge"><script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"          data-sap-ui-libs="sap.ui.commons, sap.suite.ui.commons"          data-sap-ui-theme="sap_gold_reflection"></script><!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required --><script type="text/javascript" src="https://www.google.com/jsapi"></script><script type="text/javascript">          // Load the Google Onscreen Keyboard API          google.load("elements", "1", {                    packages : "keyboard"          });          //Create a matrix layout with 2 columns          var oMatrix = new sap.ui.commons.layout.MatrixLayout({                    layoutFixed : true,                    width : '300px',                    columns : 2          });          oMatrix.setWidths('100px', '300px');          //Create a header          var oCell = new sap.ui.commons.layout.MatrixLayoutCell({                    colSpan : 4          });          oCell.addContent(new sap.ui.commons.TextView({                    text : 'Virtual Keyboard on SAPUI5 App',                    design : sap.ui.commons.TextViewDesign.H1          }));          oMatrix.createRow(oCell);          oLabel = new sap.ui.commons.Label({                    text : 'First Name'          });          oInputField = new sap.ui.commons.TextField();          oLabel.setLabelFor(oInputField);          oMatrix.createRow(oLabel, oInputField);          oLabel = new sap.ui.commons.Label({                    text : 'Last Name'          });          oInputField = new sap.ui.commons.TextField();          oLabel.setLabelFor(oInputField);          oMatrix.createRow(oLabel, oInputField);          oLabel = new sap.ui.commons.Label({                    text : 'Password'          });          oInputField = new sap.ui.commons.PasswordField();          oLabel.setLabelFor(oInputField);          oMatrix.createRow(oLabel, oInputField);          oLabel = new sap.ui.commons.Label({                    text : 'About'          });          oTextArea = new sap.ui.commons.TextArea({                    cols : 30,                    rows : 4,          });          oLabel.setLabelFor(oTextArea);          oMatrix.createRow(oLabel, oTextArea);          // Attach the layout to the page          oMatrix.placeAt("content");          var noteTaker = new sap.suite.ui.commons.NoteTaker({                    id : "NT",                    visibleNotes : 1          });          noteTaker.placeAt("content");          function onLoad() {                    var kbd = new google.elements.keyboard.Keyboard(                                        [ google.elements.keyboard.LayoutCode.HINDI ]);          }          google.setOnLoadCallback(onLoad);</script></head><body class="sapUiBody" role="application">          <div id="content"></div></body></html>

 

As per code, I am loading Google OnScreen Keyboard API and then creating keyboard instance by setting LayoutCode to language HINDI and later to ENGLISH.

 

As per API, keyboard instance takes 2 parameters as layouts and textfieldIds. Please see below information from documentation.

Keyboard(layouts, textfieldIds) creates a new Virtual Keyboard instance, where:

  • layouts is an array of keyboard layouts to preload, specified in the form of the LayoutCode enum (for example,google.elements.keyboard.LayoutCode.RUSSIAN). The first layout is the default. See the LayoutCode enum for a complete list of supported scripts.

 

Note: The API throws an exception if you supply an invalid value for the layouts array.

  • textfieldIds is an optional array containing strings of text field IDs or element references allowing you to attach the keyboard to the UI. If you don't supply the optional array, the same keyboard instance applies to any input box or text area on your page.

 

In my application, I am not supplying any text field IDs and hence I am able to use it for all available input fields.

 

P.S.-  as per documentation, this API got deprecated. But still we can use it.

 

This is one of the way we can integrate virtual keyboard. You may found other open source APIs by which you can integrate virtual keyboard with SAPUI5 application.

 

I hope you enjoyed reading this blog. Please share your thoughts and comments!

How to use WebSQL Databases in HTML5

$
0
0

Using HTML5, web pages can store data locally within the user's browser.

WebSQL database defines an API for storing data in databases that can be queried using a variant of SQL.

 

There are three core methods:

1. openDatabase

2. transaction

3. executeSql

 

Creating and Opening Databases(openDatabase)

If you try to open a database that doesn’t exist, the API will create it on the fly for you using openDatabase method.

To create and open a database, use the following code:

 

var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);


I’ve passed four arguments to the openDatabase method. These are:

  1. Database name
  2. Version number
  3. Text description
  4. Estimated size of database

 

Transactions(transaction)

Once we have opened our database, we can create transactions. The transactions give us the ability to rollback the query transactions.

i.e., if a transaction — which could contain one or more SQL statements — fails (either the SQL or the code in the transaction), the updates to the database are never committed — i.e. it’s as if the transaction never happened.

in single word we can say, transaction obeys, ATOMICITY property of DBMS.

There are also error and success callbacks on the transaction, so you can manage errors, but it’s important to understand that transactions have the ability to rollback changes.

 

 

db.transaction(function(query){
  // write SQL statements here using the "query" object
});

 

 

executeSql

 

executeSql is used for both read and write statements, includes SQL injection projection, and provides a callback method to process the results of any queries you may have written.

 

 

db.transaction(function(query){
  query
.executeSql('CREATE TABLE foo (id unique, text)');
});

 

Sample HTML Code:-


<!doctype html>

<html>

<head>

<script>

//Create DB Connection

var db =openDatabase('mydb','1.0','testdb',1024);

//Create table under the above DB

db.transaction(function(query){

query.executeSql('create table if not exists user(id unique, usesr, passwd)');

});

//Insert values to the table

db.transaction(function(query){

query.executeSql('insert into user values (1,"jai","pass")');

});

//Get stored values from the table

db.transaction(function(query){

query.executeSql('select * from user',[],function(u,results){

document.write('lenght => '+results.rows.length)

});

});

</script>

</head>

</html>

 

 

Output:-(Executed in Google Chrome)

 

WebSQL.png

Viewing all 789 articles
Browse latest View live




Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596344.js" async> </script>