Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
konstantin_anikeev
Active Contributor

Target of this post is to give an example of simple handling of the views in SAPUI5 mobile application.

Before reading this post it can be useful to read an official SAPUI5 Developers Guide for Mobile Developments

Example is represented by a simple mobile sapui5 application with 3 views and navigation between them.

Login page will take a login and password and make an authentication via service call.

View mainView represents a list of Simpsons Family. View detailView shows details to each person.

Project structure

Application has been built with Microsoft WebMatrix.

Struck out files are generated automatically and actually not needed, if you work with another editor.

  • Default.cshtml file is a default handler for the site.
  • App_Code is a reserved folder name and used for storage of C# code.
    • LoginData.cs - Namespace LoginData which is used for generation of json response with a list of members
  • i - folder with the images
  • j - folder with customer javascript files
    • app.js - common application logic and definition of global variables and functions
  • s - folder with service handlers
    • login.cshtml - handler for login action.
    • family.cshtml - handler for
  • v - folder with the application views
    • appView - main view for Application - container for all other components
    • loginView - view with input fields for login and password
    • mainView - view with a common list
    • detailView - view with details

Default.cshtml

This file is called by default on IIS with ASP.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Logon Mobile</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <script id="sap-ui-bootstrap"
                type="text/javascript"
                src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"
                data-sap-ui-language="en_US"
                type="text/javascript"
                data-sap-ui-libs="sap.m,sap.makit"
                data-sap-ui-theme="sap_mvi"></script>
        <script type="text/javascript" src="j/app.js"></script>
    </head>
    <body class="sapUiBody">
      <div id="content"></div>
    </body>
</html>

Here is an explanation of included parts.

First special part is including and initializing SAPUI5 library as described in developer guide.

   <script id="sap-ui-bootstrap" 
                type="text/javascript" 
                src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"  
                data-sap-ui-language="en_US" 
                type="text/javascript" 
                data-sap-ui-libs="sap.m,sap.makit"  
                data-sap-ui-theme="sap_mvi"></script> 

Second special part is calling own initialization logic, which is placed in app.js file.

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

app.js

app.js is a customer file with own customer logic.

This file is loaded by the load of initial page.

var oApplication = {}; // Global application object
oApplication.views = {}; // Global views reference via application object
oApplication.loadViews = function ()
// LoadViews method for loading views
// in case of successfull login
{
    this.loadView("mainView");
    this.loadView("detailView");
}
oApplication.loadView = function( sViewName )
// LoadView method for loading a single view
// and assigning it to application
{
          if (typeof this.views[sViewName] == "undefined"){
        var sViewFullName = "v."+sViewName;
        this.views[sViewName] = new sap.ui.xmlview(sViewName, sViewFullName);
        this.app.addPage( this.views[sViewName] );
          }   
}
sap.ui.localResources("v"); // setting views folder
// Loading a main application view - container for all other views
sap.ui.xmlview("appView", "v.appView").placeAt("content");

appView

Application view consists of 2 files: view definition and view controller.

appView.view.xml

View definition

<core:View controllerName="v.appView" xmlns="sap.m"
    xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
    xmlns:html="http://www.w3.org/1999/xhtml">   
    <App id="appLogin">
        <mvc:XMLView id="loginView" viewName="v.loginView"></mvc:XMLView>
    </App>
</core:View>

Main view has a definition of the mobile application and single default view loginView.

appView.controller.js

Controller for common view

sap.ui.controller("v.appView", {
    onInit: function () {
        oApplication.app = this.getView().byId("appLogin");
    }
});

Controller is very simple. By initialization of the application view a reference to sap.m.app (Mobile Application by SAPUI5) is assigned to an app attribute of the global variable oApplication.

loginView

Login view consists of 2 files: view definition and view controller.

loginView.view.xml

View definition

<core:View height="100%" controllerName="v.loginView"
    xmlns="sap.m" xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:html="http://www.w3.org/1999/xhtml">   
    <Page id="loginPage" enableScrolling="false" title="Login Mobile">
                              <VBox fitContainer="true" justifyContent="Center" alignItems="Center">
                                        <Label id="lblLogin" text="Login" design="Bold" labelFor="inpLogin" />
                                        <Input id="inpLogin" editable="true" value="" maxLength="20"/>
                                        <Label id="lblPWD" text="Password" design="Bold"  labelFor="inpPWD"/>
                                        <Input id="inpPWD" type="Password" editable="true" value="" maxLength="20" />
                                        <Button id="bntLogin" text="Login" tap="actLogin" />
                              </VBox>
    </Page>
</core:View>

This view should look like this (design for iOS)

By tap on Login button a method actLogin of view controller is called.

loginView.controller.js

sap.ui.controller("v.loginView", {
    actLogin: function () {
        var sURL = "/s/login.cshtml?login=" + this.byId("inpLogin").getValue() +
                    "&password" + this.byId("inpPWD").getValue(); // compile URL to call
        $.ajax({
            url: sURL,
            dataType: "json", // expecting json response
            success: function (data) {
                oApplication.loadViews();
                oApplication.app.to("mainView");
            }
        });
    }
});

Controller has only one method actLogin, which performs authorisation.

Please pay attention, that this post is only an example for SAPUI5 navigation. Security issues are not in scope. In real world you should not pass plain login and password as get parameters.

login.cshtml

Login service has no logic and sends back only a positive json response.

@{
    Response.Clear();
    Response.ContentType = "application/json";
    Response.Write( "{\"loginresult\":\"success\"}" );   
    Response.SetStatus( HttpStatusCode.OK );
    Response.Flush();
    Response.Close();                        
}

Response looks like a json: {"loginresult":"success"}

Response is not processed is this example. Application just goes further.

It calls oApplication.loadViews() first to load and assign views to application.

Then a navigation method oApplication.app.to("mainView") is called. In that case navigation performed via view name.

mainView

Main view has a list with a members of Simpsons family. It consists just from the List with names.

mainView.view.xml

<core:View height="100%" controllerName="v.mainView"
    xmlns="sap.m" xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:html="http://www.w3.org/1999/xhtml">   
    <Page id="mainView" title="Family">
        <List id="lstFamily" items="{/persons}">
            <StandardListItem title="{lastname}" description="{firstname}"
            type="Navigation" tap="actItemTapped" />
        </List>
    </Page>
</core:View>

View has a List, which is bound to a model. Items are taken from node persons; Title and description of single item are taken from properties of node items.

JSON looks like a very simple structure:

This structure is taken by initialization of the view controller.

mainView.controller.js

sap.ui.controller("v.mainView", {    
          onInit: function(){
                    var view = this.getView();
                    $.ajax( "/s/family.cshtml",
                              {  
                dataType: "json",
                                        success: function(data){
                                        var oModel = new sap.ui.model.json.JSONModel(data);
                                                  view.byId("lstFamily").setModel(oModel);
                                        }
                              }
    );
          },
 
  actItemTapped: function(evt) {
                    oApplication.app.to(oApplication.views.detailView, evt.oSource.oBindingContext);
  }
});

By the initialization a service family.cshtml asked for a list of persons.

Additionally an event handler for list item tap implemented. It has only navigation call.

family.cshtml

Service definition, which just formats a correct json response.

@using LoginData;
@using System.Web.Script.Serialization;
@{
    Persons jsonResponse = new Persons();
    jsonResponse.persons.Add(
          new PersonData("Homer", "Simpson", "Big boss", "male", "/i/Homer.png"));
    jsonResponse.persons.Add(
          new PersonData("Marge", "Simpson", "First lady", "female", "/i/Marge.png"));
    jsonResponse.persons.Add(
          new PersonData("Bartholomew", "Simpson", "Hooligan", "male", "/i/Bart.png"));
    jsonResponse.persons.Add(
          new PersonData("Lisa Marie", "Simpson", "Nerd", "female", "/i/Lisa.png"));
    Response.Clear();
    Response.ContentType = "application/json";
    JavaScriptSerializer js = new JavaScriptSerializer();   
    Response.Write( js.Serialize(jsonResponse) );   
    Response.SetStatus( HttpStatusCode.OK );
    Response.Flush();
    Response.Close();                        
}

Here a namespace LoginData is used. This namespace is defined in the file LoginData.cs.

LoginData.cs

Type definition for json response.

using System;
using System.Collections.Generic;
using System.Web;
namespace LoginData{
    public class PersonData{
        public PersonData( string firstname, string lastname, string status, string gender, string image ){
            this.firstname = firstname;
            this.lastname = lastname;
            this.status = status;
            this.gender = gender;
            this.image = image;
        }
        public string firstname;
        public string lastname;
        public string status;
        public string gender;
        public string image;
    }
    public class Persons{
        public Persons(){
            persons = new List<PersonData>();
        }
        public List<PersonData> persons;
    }
}

Result view should looks like following screenshot.

detailView

Main view has a list with single attributes of person.

detailView.view.xml

<core:View height="100%" controllerName="v.detailView"
    xmlns="sap.m" xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:html="http://www.w3.org/1999/xhtml">   
    <Page id="detailPage" showNavButton="true" title="Person" navButtonTap="actBack">
                    <List id="lstPerson">
                        <DisplayListItem label="Lastname:" value="{lastname}" />
                        <DisplayListItem label="Firstname:" value="{firstname}" />
                        <DisplayListItem label="Gender:" value="{gender}" />
                        <DisplayListItem label="Status:" value="{status}" />
                    </List>
        <Image src="{image}" />
    </Page>
</core:View>

detailView.controller.js

Controller of detail view has 2 methods.

sap.ui.controller("v.detailView", {   
          onInit: function(){ // binding model synchronisation
                    this.getView().addDelegate({ onBeforeShow: function(evt) {
                              if (this.direction != "back") {
                                        evt.to.setModel(evt.data.oModel);
                                        evt.to.setBindingContext(evt.data);
                              }
                    }});
          },
          actBack: function() {
                    oApplication.app.back();
          }
});

onInit method binds an onBeforeShow event of the detail view with actual selected person via the model.

actBack method just handles a navigation back to the previous view.

As a Result a detailView should looks like following screenshots.

P.S.

Try to add Maggie

Labels in this area