Category: UI5 Programs

  • Google Firebase Setup

    Introduction

    Welcome to the ultimate guide for setting up Google Firebase! Whether you’re a beginner or an experienced developer, this comprehensive tutorial will walk you through the process of setting up Firebase for your project. Firebase provides a suite of powerful services and tools that can help you build, improve, and scale your applications with ease.

    In this step-by-step tutorial, we will cover all the necessary steps to get your Firebase project up and running. We’ll start by creating a Firebase project and selecting the services that best fit your application’s needs. Whether you want to incorporate user authentication, real-time data storage, cloud storage, or even hosting, Firebase has got you covered.

    We’ll guide you through the process of configuring Firebase Authentication to secure your app and allow users to log in using various methods. You’ll also learn how to integrate the Realtime Database or Cloud Firestore to store and synchronize data in real-time across multiple devices. If you need to handle file uploads or downloads, we’ll show you how to set up Firebase Cloud Storage. And if you’re building a web app, we’ll explore the process of deploying your app using Firebase Hosting.

    No matter the platform you’re developing for, whether it’s web, mobile, or even desktop, Firebase offers SDKs and resources to support your development needs. We’ll provide platform-specific guidance to help you seamlessly integrate Firebase into your app.

    By the end of this tutorial, you’ll have a fully functional Firebase setup, ready to power your application with robust features and services. Get ready to unlock the full potential of Google Firebase and take your project to new heights.

    Let’s dive in and begin the journey of setting up Google Firebase for your next groundbreaking application!

    Steps to Google Firebase Setup

    To set up Google Firebase, follow these steps:

    1. Create a Firebase project: Visit the Firebase website (firebase.google.com) and sign in with your Google account. Click on “Go to Console” and then select “Add project.” Provide a name for your project and choose your desired region.

    2. Set up Firebase services: Once your project is created, you can select the Firebase services you want to use. Firebase offers a wide range of services, including Authentication, Realtime Database, Cloud Firestore, Cloud Storage, Hosting, and more. Enable the services you need for your project.

    3. Configure Firebase Authentication (optional): If you want to add user authentication to your app, navigate to the Authentication section in the Firebase console. Follow the instructions to configure the authentication providers you want to support, such as email/password, Google Sign-In, or Facebook Login.

    4. Set up Firebase SDK: To connect your app with Firebase, you need to add the Firebase SDK to your project. Depending on your platform (web, Android, iOS, etc.), Firebase provides specific SDKs and instructions. For web projects, you typically need to include a script tag with the Firebase SDK initialization code in your HTML file.

    5. Integrate Firebase into your app: Follow the integration instructions provided by Firebase for your specific platform. This may involve adding initialization code, configuring Firebase services, and setting up the necessary API keys or credentials. Firebase provides comprehensive documentation and guides for each platform to help you with the integration process.

    6. Test your Firebase setup: Once you have integrated Firebase into your app, it’s essential to test the functionality. You can use Firebase’s emulator suite or run your app on a real device to ensure that the Firebase services are working correctly. Test features such as authentication, database access, storage, and any other Firebase services you’ve incorporated into your app.

    7. Deploy your app (if applicable): If you’re building a web app and using Firebase Hosting, you can deploy your app directly from the Firebase console. Follow the hosting setup instructions to configure your hosting settings and deploy your app to Firebase Hosting. This allows you to serve your app’s static assets and content from Firebase’s global CDN.

    By following these steps, you can successfully set up Google Firebase for your project and begin leveraging its powerful suite of services. Remember to consult the Firebase documentation for detailed instructions specific to your chosen platform. Happy Firebase development!

  • Connecting a UI5 Web App with Google Firebase

    [et_pb_section admin_label=”section”] [et_pb_row admin_label=”row”] [et_pb_column type=”4_4″][et_pb_text admin_label=”Text”]

    Introduction

    Are you looking to connect your UI5 web application with the powerful capabilities of Google Firebase? Look no further! In this comprehensive tutorial, we will guide you through the process of seamlessly integrating your UI5 web app with Google Firebase, allowing you to leverage Firebase’s robust features for authentication, real-time database, cloud storage, and more.

    Connecting a UI5 web app with Google Firebase opens up a world of possibilities for enhancing your application’s functionality and user experience. With Firebase’s easy-to-use APIs and intuitive interfaces, you can effortlessly incorporate features like user authentication, allowing your users to securely log in and access personalized content. Additionally, Firebase’s real-time database empowers you to create dynamic, collaborative applications by enabling instant data synchronization across multiple devices.

    But that’s not all! By integrating Firebase’s cloud storage, you can effortlessly store and retrieve files, images, and other media assets, ensuring a seamless experience for your users. And with Firebase’s powerful hosting capabilities, deploying and scaling your UI5 web app becomes a breeze.

    In this tutorial, we will provide you with a step-by-step guide, complete with code examples and best practices, to ensure a smooth and successful integration process. Whether you’re a UI5 developer looking to enhance your app’s functionality or an aspiring developer eager to learn about the power of Firebase, this tutorial is perfect for you.

    Unlock the true potential of your UI5 web app by connecting it with Google Firebase. Join us on this exciting journey and take your application development to new heights!

    Steps for Connecting a UI5 Web App with Google Firebase

    To connect a UI5 web app with Google Firebase set up a Firebase project. Visit the Firebase console (console.firebase.google.com) and create a new project. Provide a name for your project and choose the desired Firebase services you want to use, such as Authentication, Realtime Database, Cloud Storage, and Hosting.

    Step 01: Create an App in Firebase

    Step 02: Create a new UI5 App, and add these firebase scripts within index.html

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>firebaseApp</title>
            <script id="sap-ui-bootstrap"
                src="resources/sap-ui-core.js"
                data-sap-ui-theme="sap_fiori_3"
                data-sap-ui-resourceroots='{"firebaseApp.firebaseApp": "./"}'
                data-sap-ui-compatVersion="edge"
                data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
                data-sap-ui-async="true"
                data-sap-ui-frameOptions="trusted">
            </script>
             <!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
      <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-app.js"></script>
    
      <!-- If you enabled Analytics in your project, add the Firebase SDK for Analytics -->
      <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-analytics.js"></script>
    
      <!-- Add Firebase products that you want to use -->
      <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-auth.js"></script>
      <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-firestore.js"></script>
      <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-database.js"></script>
      <script src="https://www.gstatic.com/firebasejs/7.23.0/firebase-storage.js"></script>
      <script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-functions.js"></script>
            
        </head>
        <body class="sapUiBody">
            <div data-sap-ui-component data-name="firebaseApp.firebaseApp" data-id="container" data-settings='{"id" : "firebaseApp"}'></div>
        </body>
    </html>

     

    Step 03: Create a new file Firebase.js in js folder and given code:

    sap.ui.define([
        "sap/ui/model/json/JSONModel",
    ], function (JSONModel) {
        "use strict";
        return {
            // Firebase-config retrieved from the Firebase-console
            initializeFirebase: function () {
                // Replace with your config here
                const firebaseConfig = {
                    apiKey: "<your API Key>",
                    authDomain: "<your authDomain>",
                    projectId: "<your projectId>",
                    storageBucket: "<your storageBucket>",
                    messagingSenderId: "<your messagingSenderId>",
                    appId: "<your appId>",
                    measurementId: "<your measurementId>"
                };
                // Initialize Firebase with the Firebase-config
                firebase.initializeApp(firebaseConfig);
    
                // Create a Firestore reference
                const firestore = firebase.firestore();
    
                // Create a Authentication reference
                const fireAuth = firebase.auth();
    
                // Get Firebase Instance
                const oFirestore = firebase.firestore;
    
                // Create a Fire Storage reference
                const fireStorage = firebase.storage();
    
                // Create a Fire Functions reference
                const fireFunctions = firebase.app().functions('asia-east2');
    
                // Firebase services object
                const oFirebase = {
                    firestore: firestore,
                    fireAuth: fireAuth,
                    oFirestore: oFirestore,
                    fireStorage: fireStorage,
                    fireFunctions: fireFunctions
                };
    
                // Create a Firebase model out of the oFirebase service object which contains all required Firebase services
                var fbModel = new JSONModel(oFirebase);
    
                // Return the Firebase Model
                return fbModel;
            }
        };
    });

    Step 04: Set Firebase Model in component.js as shown below:

    sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/Device",
        "Healthbridge-admin/Healthbridge-admin/model/models",
        "Healthbridge-admin/Healthbridge-admin/js/Firebase"
    ], function (UIComponent, Device, models, Firebase) {
        "use strict";
    
        return UIComponent.extend("Healthbridge-admin.Healthbridge-admin.Component", {
    
            metadata: {
                manifest: "json"
            },
    
            /**
             * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
             * @public
             * @override
             */
            init: function () {
                // call the base component's init function
                UIComponent.prototype.init.apply(this, arguments);
    
                // enable routing
                this.getRouter().initialize();
    
                // set the device model
                this.setModel(models.createDeviceModel(), "device");
    
                // set the app Config model
                this.setModel(models.createAppConfigModel(), "AppConfig");
    
                //set Firebase Model
                this.setModel(Firebase.initializeFirebase(), "fbModel");
    
            }
        });
    });

    Step 05: Check if you can fetch Authentication details by using the below code in onInit or _handleRouteMatched or onAfterRendering

    var fireAuth = this.getView().getModel("fbModel").getData().fireAuth;
    console.log(fireAuth);

     

     

     [/et_pb_text][/et_pb_column] [/et_pb_row] [/et_pb_section]

  • How to Generate Mock Data in UI5

    Introduction

    As a UI5 developer or a UI5 tester, you may often need to generate mock data for testing your apps. This can be a time-taking task, especially when you need to test a large amount of data. Fortunately, we have several tools provided by SAP to make this process faster and more efficient. In this article, we will explore the best practices for generating mock data in UI5.

    What is a Mock Data?

    Mock data, also known as fake data or dummy data, is data that is created for the purpose of testing or demonstrating a software application without using real production data. Mock data is often used in software development to simulate different scenarios or test the functionality of an application under different conditions. Mock data can be used to create test cases, generate sample data for demos, or simulate user behavior for usability testing. The data used in mock data can be randomly generated or created manually to mimic the format and structure of real data. Using mock data helps ensure that software applications are tested thoroughly before they are released to end-users and that they function correctly under a wide range of conditions.

    When do we need Mock Data in SAP UI5?

    Mock data is commonly used in SAP UI5 development for several reasons, including:

    1. Testing: Mock data is used to test the application’s functionality under different conditions without the need for real data. It helps to identify and fix any issues before the application is deployed in a production environment.
    2. Prototyping: Mock data is useful for quickly prototyping and demonstrating the application’s features and functionality without having to connect to real data sources.
    3. Performance: Using real data during the development process can slow down the application’s performance. Mock data helps developers test and optimize the application’s performance before deploying it in a production environment.
    4. Security: Mock data can be used to ensure that sensitive or confidential data is not exposed during development and testing.

    Overall, using mock data in SAP UI5 development helps to reduce development time and costs while ensuring that the application meets the requirements and functions as expected.

    Steps to Generate Mock Data in SAP UI5

    There are several methods for generating mock data in SAP UI5, depending on your specific needs and preferences. Here are some general steps that you can follow to generate mock data in SAP UI5:

    1. Identify the data requirements: Determine the type of data and the format needed for your application. This may include data types, fields, and data structure.
    2. Choose a method: Select the method that best suits your needs for generating mock data. You can use online tools, create custom scripts, or leverage existing data sources.
    3. Generate the mock data: Use the chosen method to generate the mock data. If using an online tool, enter the data requirements and follow the prompts to generate the data. If creating custom scripts, use JavaScript or other scripting languages to create the data.
    4. Save the mock data: Save the generated mock data in a JSON format or any other format that is compatible with SAP UI5.
    5. Integrate the mock data: Use the mock data in your SAP UI5 application by either manually including it in your code or loading it dynamically from a JSON file.
    6. Test the application: Test the application with the mock data to ensure that it functions correctly under different conditions.

    Overall, generating mock data in SAP UI5 requires careful planning, selecting the right method, and thorough testing to ensure that the application functions as expected.

    Generate Custom Mock Data in SAP UI5

    How to Generate Mock Data in UI5 using WebIDE

    Following are the steps to generate Mock Data in SAP UI5 using WebIDE:

    Step 01: Create a new UI5 project (Neo or Cloud Foundry) in SAP WebIDE

    Step 02: Download the metadata (e.g. of Northwind from here: https://services.odata.org/v2/northwind/northwind.svc/$metadata)

    Step 03: Right-click on the project folder and click Import OData, and use the file downloaded above to import the same.

    Step 04: Once imported, do not change anything in Manfiest.xml, ui5.yaml file or servicebinding.js file. You will see a new file “metadata.xml” within the folder “localService” Right click on the file and click “Edit Mock Data”.

    Edit Mock Data

    Step 05: There you need to choose your entityset (in our usecase Products) and click the button “Generate Random Data”

    generate random data

    Step 06: In your view file, create a table and bind one of the entityset (in our usecase Products) to items, and the fields of the same within the table fields.

    Step 07: Run your web app using a new configuration, and mark “Run using mockdata” checkbox.

    That’s it, your mockdata would be binded with your table.

    Output of Mock Data

    Code

    Manifest File:

    {
        "_version": "1.12.0",
        "sap.app": {
            "id": "MockData.MockData",
            "type": "application",
            "i18n": "i18n/i18n.properties",
            "applicationVersion": {
                "version": "1.0.0"
            },
            "title": "{{appTitle}}",
            "description": "{{appDescription}}",
            "sourceTemplate": {
                "id": "servicecatalog.connectivityComponentForManifest",
                "version": "0.0.0"
            },
            "dataSources": {
                "NorthwindModel": {
                    "uri": "/here/goes/your/serviceurl/",
                    "type": "OData",
                    "settings": {
                        "localUri": "localService/metadata.xml"
                    }
                }
            }
        },
        "sap.ui": {
            "technology": "UI5",
            "icons": {
                "icon": "",
                "favIcon": "",
                "phone": "",
                "phone@2": "",
                "tablet": "",
                "tablet@2": ""
            },
            "deviceTypes": {
                "desktop": true,
                "tablet": true,
                "phone": true
            }
        },
        "sap.ui5": {
            "flexEnabled": false,
            "rootView": {
                "viewName": "MockData.MockData.view.View1",
                "type": "XML",
                "async": true,
                "id": "View1"
            },
            "dependencies": {
                "minUI5Version": "1.65.6",
                "libs": {
                    "sap.ui.layout": {},
                    "sap.ui.core": {},
                    "sap.m": {}
                }
            },
            "contentDensities": {
                "compact": true,
                "cozy": true
            },
            "models": {
                "i18n": {
                    "type": "sap.ui.model.resource.ResourceModel",
                    "settings": {
                        "bundleName": "MockData.MockData.i18n.i18n"
                    }
                },
                "": {
                    "type": "sap.ui.model.odata.v2.ODataModel",
                    "settings": {
                        "defaultOperationMode": "Server",
                        "defaultBindingMode": "OneWay",
                        "defaultCountMode": "Request"
                    },
                    "dataSource": "NorthwindModel",
                    "preload": true
                }
            },
            "resources": {
                "css": [
                    {
                        "uri": "css/style.css"
                    }
                ]
            },
            "routing": {
                "config": {
                    "routerClass": "sap.m.routing.Router",
                    "viewType": "XML",
                    "async": true,
                    "viewPath": "MockData.MockData.view",
                    "controlAggregation": "pages",
                    "controlId": "app",
                    "clearControlAggregation": false
                },
                "routes": [
                    {
                        "name": "RouteView1",
                        "pattern": "RouteView1",
                        "target": [
                            "TargetView1"
                        ]
                    }
                ],
                "targets": {
                    "TargetView1": {
                        "viewType": "XML",
                        "transition": "slide",
                        "clearControlAggregation": false,
                        "viewId": "View1",
                        "viewName": "View1"
                    }
                }
            }
        }
    }

     

    Service Binding File:

    function initModel() {
        var sUrl = "/here/goes/your/serviceurl/";
        var oModel = new sap.ui.model.odata.ODataModel(sUrl, true);
        sap.ui.getCore().setModel(oModel);
    }

     

    View File:

    <mvc:View controllerName="MockData.MockData.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Generate Custom Mock Data in SAP UI5">
                        <content>
                            <Table items="{/Products}">
                                <columns>
                                    <Column width="12em">
                                        <Text text="Product"/>
                                    </Column>
                                    <Column minScreenWidth="Tablet" demandPopin="true">
                                        <Text text="Supplier"/>
                                    </Column>
                                </columns>
                                <items>
                                    <ColumnListItem vAlign="Middle">
                                        <cells>
                                            <ObjectIdentifier title="{ProductName}" text="{ProductId}"/>
                                            <Text text="{SupplierID}"/>
                                        </cells>
                                    </ColumnListItem>
                                </items>
                            </Table>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    How to Generate Mock Data in UI5 using BAS

    The content will be added soon.

  • Create a SAP UI5 Project using ChatGPT

    What are SAP UI5 Projects and why do we need them?

    SAP UI5 (SAP User Interface for HTML5) is a JavaScript-based framework for building web applications that run on desktop, tablet, and mobile devices. It provides a set of UI controls, libraries, and tools for creating modern, responsive, and scalable user interfaces.

    The SAP UI5 framework is used to develop web-based applications that can be integrated with SAP systems and other enterprise systems. It helps in creating a consistent user experience across multiple devices, improves application performance, and reduces development time and costs. Additionally, it provides a set of pre-built UI controls and components, making it easier for developers to create and maintain complex applications.

    Overall, SAP UI5 projects are needed for creating modern and efficient web-based applications that can integrate with SAP systems and other enterprise systems, improving the user experience and simplifying the development process.

    How to do setup for SAP UI5 Development

    Here are the steps to set up your development environment for SAP UI5:

    A. Using IDE in Windows

    1. Install SAP Web IDE or Eclipse or VS Code: SAP Web IDE is a development environment for SAP UI5 applications. You can obtain it through the SAP Developer Center or through the SAP Cloud Platform account.
      Download SAP Web IDE for Windows here: https://tools.hana.ondemand.com/#sapui5
      Download Eclipse for Windows from here: https://www.eclipse.org/downloads/packages/
      Download Visual Studio Code from here: https://code.visualstudio.com/download
    2. Install Required Software: You will need to have the following software installed on your development machine:
      • Node.js and npm (Node Package Manager)
      • Git command-line tools
      • A code editor of your choice, such as Visual Studio Code, Sublime Text, or Eclipse.
    3. Clone the UI5 Template Project: You can clone the UI5 Template Project from the SAP UI5 GitHub repository, which provides a basic structure for a SAP UI5 application.
    4. Install the Required Dependencies: Once you have cloned the UI5 Template Project, navigate to the project folder and run the following command to install the required dependencies:
      npm install
    5. Start the Development Server: To start the development server, run the following command in the project folder:
      npm start
    6. Access the Application: You can access the application in your web browser at the URL http://localhost:8080. You should now see the SAP UI5 application running in your browser.

    These are the basic steps to set up your environment for SAP UI5 development. Once your environment is set up, you can start building and customizing your SAP UI5 applications.

    B. Using SAP Web IDE

    Here are the steps to set up SAP WebIDE for SAP UI5 development:

    1. Sign up for SAP Developer Center: If you don’t already have an SAP Developer Center account, you can sign up for one at the SAP Developer Center website.
    2. Access SAP WebIDE: After signing up for an SAP Developer Center account, you can access SAP WebIDE from the SAP Cloud Platform account.
    3. Create a New Project: To create a new SAP UI5 project in SAP WebIDE, click on the “New Project” button, select the “SAP UI5 Application” project type, and give your project a name.
    4. Choose a Project Template: You can choose from a variety of project templates, including a basic template, a master-detail template, and a blank template.
    5. Configure the Project Settings: You can configure the project settings such as the title, description, and target device type.
    6. Start Coding: Once the project is set up, you can start coding your SAP UI5 application in SAP WebIDE. SAP WebIDE provides a code editor, debugging tools, and other tools to help you develop and test your application.
    7. Deploy the Application: When your application is ready to be deployed, you can deploy it directly from SAP WebIDE to an SAP Cloud Platform account or to an on-premise SAP system.

    These are the steps to set up SAP WebIDE for SAP UI5 development. With SAP WebIDE, you can quickly and easily create, develop, and deploy SAP UI5 applications.

    C. Using SAP Business Application Studio (BAS)

    Here are the steps to set up SAP Business Application Studio (BAS) for SAP UI5 development:

    1. Sign up for SAP Business Application Studio: If you don’t already have an SAP Business Application Studio account, you can sign up for one from the SAP Developer Center.
    2. Launch SAP Business Application Studio: After signing up for SAP Business Application Studio, you can launch it from the SAP Cloud Platform account.
    3. Create a New Workspace: To create a new workspace in SAP Business Application Studio, click on the “Create Workspace” button and give your workspace a name.
    4. Choose a Project Template: You can choose from a variety of project templates, including a basic template, a master-detail template, and a blank template.
    5. Configure the Project Settings: You can configure the project settings, such as the title, description, and target device type.
    6. Start Coding: Once the project is set up, you can start coding your SAP UI5 application in SAP Business Application Studio. SAP Business Application Studio provides a code editor, debugging tools, and other tools to help you develop and test your application.
    7. Deploy the Application: When your application is ready to be deployed, you can deploy it directly from SAP Business Application Studio to an SAP Cloud Platform account or to an on-premise SAP system.

    These are the steps to set up SAP Business Application Studio (BAS) for SAP UI5 development. With SAP Business Application Studio, you can quickly and easily create, develop, and deploy SAP UI5 applications and take advantage of cloud-based development tools and infrastructure.

    How to use ChatGPT to create an SAP UI5 Project

    Step 01: Visit ChatGPT Portal: https://chat.openai.com/chat

    Step 02: Type your query; you can ask regarding a single step related to your UI5 issue or can ask ChatGPT to generate code for the entire project. We will ask ChatGPT to create a project with table forms and CRUD operations.

    Step 03: We asked ChatGPT to create a UI5 project that shows a table of a customer, with buttons on the top to create a new record, edit the existing record and delete a record by selecting a radio button within the table. We got the given output:

    Use ChatGPT to generate ui5 code

    Here is an example of how you could create a UI5 project to show a table of customers with the desired buttons for creating, editing, and deleting records:

    1. Start by creating a new UI5 project in the SAP Web IDE. In our project, we called it “ChatGPTGen”.
    2. Create a new XML view for the table of customers, which will include the buttons for creating, editing, and deleting records.
      <mvc:View controllerName="ChatGPTGen.ChatGPTGen.controller.Main" xmlns:table="sap.ui.table" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
          <Shell id="shell">
              <App id="app">
                  <pages>
                      <Page id="page" title="ChatGPT Generated UI5 Project">
                          <content>
                              <table:Table id="customerTable" selectionMode="Single" rows="{/customers}" enableColumnReordering="false">
                                  <!-- columns for customer name, address, and email -->
                                  <table:columns>
                                      <table:Column width="20%">
                                          <table:label>
                                              <Label text="Name"/>
                                          </table:label>
                                          <table:template>
                                              <Text text="{name}"/>
                                          </table:template>
                                      </table:Column>
                                      <table:Column width="30%">
                                          <table:label>
                                              <Label text="Address"/>
                                          </table:label>
                                          <table:template>
                                              <Text text="{address}"/>
                                          </table:template>
                                      </table:Column>
                                      <table:Column width="50%">
                                          <table:label>
                                              <Label text="Email"/>
                                          </table:label>
                                          <table:template>
                                              <Text text="{email}"/>
                                          </table:template>
                                      </table:Column>
                                  </table:columns>
                              </table:Table>
                          </content>
                          <!-- buttons for creating, editing, and deleting records -->
                          <footer>
                              <Bar>
                                  <contentLeft>
                                      <Button id="createButton" text="Create" press="handleCreate"/>
                                      <Button id="editButton" text="Edit" press="handleEdit"/>
                                      <Button id="deleteButton" text="Delete" press="handleDelete"/>
                                  </contentLeft>
                              </Bar>
                          </footer>
                      </Page>
                  </pages>
              </App>
          </Shell>
      </mvc:View>

       

    3. Create a new controller for the view, which will handle the actions of the buttons for creating, editing, and deleting records.
      sap.ui.define([
          "sap/ui/core/mvc/Controller"
      ], function (Controller) {
          "use strict";
      
          return Controller.extend("ChatGPTGen.ChatGPTGen.controller.Main", {
              onInit: function () {
                  var oModel = new sap.ui.model.json.JSONModel();
                  oModel.setData({
                      customers: [{
                          name: "John Doe",
                          address: "123 Main St",
                          email: "john.doe@example.com"
                      }, {
                          name: "Jane Doe",
                          address: "456 Oak Ave",
                          email: "jane.doe@example.com"
                      }]
                  });
      
                  // set the model on the core so that it is available to the entire application
                  sap.ui.getCore().setModel(oModel);
                  // bind the table to the model
                  this.byId("customerTable").setModel(sap.ui.getCore().getModel());
              },
      
              // handler for creating a new customer record
              handleCreate: function () {
                  // implement your logic for creating a new customer here
              },
      
              // handler for editing a customer record
              handleEdit: function () {
                  // get the selected customer from the table
                  var oTable = this.byId("customerTable");
                  var oSelectedCustomer = oTable.getSelectedItem();
      
                  // implement your logic for editing the selected customer here
              },
      
              // handler for deleting a customer record
              handleDelete: function () {
                  // get the selected customer from the table
                  var oTable = this.byId("customerTable");
                  var iSelectedIndex = oTable.getSelectedIndex();
      
                  // check if a customer is selected
                  if (iSelectedIndex === -1) {
                      sap.m.MessageToast.show("Please select a customer to delete");
                      return;
                  }
      
                  // remove the selected customer from the model data
                  var aCustomers = sap.ui.getCore().getModel().getData().customers;
                  aCustomers.splice(iSelectedIndex, 1);
                  sap.ui.getCore().getModel().setData({
                      customers: aCustomers
                  });
      
                  // show success message and refresh the table
                  sap.m.MessageToast.show("Your selected row is deleted");
                  // oTable.getBinding("items").refresh();
              }
      
          });
      });

       

    Output

    Create a SAP UI5 Project using ChatGPT

  • How to Integrate ChatGPT in SAP UI5

    Preface – This post is part of the UI5 Integration Programs series.

    Introduction

    It is not possible to directly integrate ChatGPT using a CDN (Content Delivery Network) as GPT-3 model is not hosted on any public CDN. GPT-3 is a proprietary model owned by OpenAI, and access to it is provided through the OpenAI API, which requires an API key to use.

    You can use the OpenAI API in your JavaScript application by making HTTP requests to the API endpoint and using the API key. The OpenAI API provides a prompt endpoint that allows you to send a prompt to GPT-3 and receive a response.

    Here’s an example of how you might use the fetch API in JavaScript to send a prompt to GPT-3 and log the response:

    const API_KEY = 'YOUR_API_KEY';
    const prompt = 'What is the meaning of life?';
    
    fetch(`https://api.openai.com/v1/engines/davinci/completions`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${API_KEY}`
        },
        body: JSON.stringify({
            prompt,
            max_tokens: 20
        })
    }).then(response => response.json())
        .then(data => {
        console.log(data.choices[0].text);
    });
    

    How to Integrate ChatGPT in SAP UI5

    As shown in below image, we will follow three simple steps to integrate ChatGPT APIs within SAP UI5 App.

    How to Integrate ChatGPT in SAP UI5

    1. Get API of Open AI

    We have already discussed all the steps involved regarding API creation in this article.

    2. Create UI5 Project

    Use Web IDE or SAP BAS and generate a simple UI5 Application using a generator.

    3. Integrate ChatGPT Call

    We have create a very simple view with input box, button and a text area to show output as shown in below view:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Get Answers from ChatGPT">
                        <content>
                            <VBox>
                                <Input id="idInput"/>
                                <Button text="Get Answer" press="onPressGPT"/>
                                <Text id="idText"/>
                            </VBox>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    And on the press of Button, we have written the given code in controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
    
            },
    
            onPressGPT: function () {
                var that = this;
                const API_KEY = '';
                var prompt = this.byId("idInput").getValue();
                fetch(`https://api.openai.com/v1/engines/davinci/completions`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Authorization': `Bearer ${API_KEY}`
                        },
                        body: JSON.stringify({
                            prompt,
                            max_tokens: 2000
                        })
                    }).then(response => response.json())
                    .then(data => {
                        that.byId("idText").setText(data.choices[0].text);
                    });
            }
        });
    });

    Output

    The Output without pressing the button looks like this:

    UI5 ChatGPT output view

  • Using models.js in SAP UI5 (to maintain all Global Models)

    Preface – This post is part of the UI5 Programs series.

    What is model.js file in SAP UI5?

    A model in terms of UI5 is a set of data (mostly in JSON format) that can be binded with elements of UI5. For different properties of different elements, the type of model data differs, for example:

    • For the property “visible” of a button, the required model (Data within the model) should be either true or false
    • For the property “text” of a button, the required model (Data within the model) should be a string
    • For the data of the table, the required model should be a JSON data
    • For the data of Drop down, the required model should be JSON data [where one field should act as a key and another as value]
    • For the data of Table count that is shown next to the table name [Example User(90)], the required model (Data within the model) should be a numeric
    • For the data of a Form, the required model should be an Object [with multiple keys and values, where each key will be an element of the form]
    • In case you need to transfer login details to multiple pages, the required model should be an Object [where the key-value pair will save ID and hashed session password/data]

    The model.js in SAP UI5 is a dedicated file to save multiple global variables that can hold data (commonly known as a model) as per requirement.

    The model data refreshes to initial values every time the browser is refreshed; hence it is recommended not to save any data that is required not to be lost during browser refresh.

    The layout of the model.js looks something like this in the folder structure:

    model.js file

    Setting up a Global Model using model.js file in SAP UI5

    There are three steps to using a Global Model.

    1. Create a model object in Model.js file

    The first step is to create a model in model.js file. The model.js file is already created within the model folder of webapp. In case their is no such file, create a file, name it “model.js” with given content:

    sap.ui.define([
        "sap/ui/model/json/JSONModel",
        "sap/ui/Device"
    ], function (JSONModel, Device) {
        "use strict";
    
        return {
    
            createDeviceModel: function () {
                var oModel = new JSONModel(Device);
                oModel.setDefaultBindingMode("OneWay");
                return oModel;
            }
    
        };
    });

    Now, we will add our own code within this file. Let us call it “createAppConfigModel” with given data:

    //app Congiguration model
    createAppConfigModel: function () {
        var appData = {
            "editable": false,
            "count": 0,
            "formData": {},
            "tableData": []
        };
        var oModel = new JSONModel(appData);
        return oModel;
    }

    Now, your Model.js will look like this:

    sap.ui.define([
        "sap/ui/model/json/JSONModel",
        "sap/ui/Device"
    ], function (JSONModel, Device) {
        "use strict";
    
        return {
    
            createDeviceModel: function () {
                var oModel = new JSONModel(Device);
                oModel.setDefaultBindingMode("OneWay");
                return oModel;
            },
            //app Congiguration model
            createAppConfigModel: function () {
                var appData = {
                    "editable": false,
                    "count": 0,
                    "formData": {},
                    "tableData": []
                };
                var oModel = new JSONModel(appData);
                return oModel;
            }
    
        };
    });

     

    2. Configure the Component.js file for the Global Model Object

    In the Component.js file, in case your Model.js file was already there, the model configuration is added like this:

    sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/Device",
        "YRR/YRR/model/models"
    ], function (UIComponent, Device, models) {
        "use strict";
    
        return UIComponent.extend("YRR.YRR.Component", {
    
            metadata: {
                manifest: "json"
            },
    
            /**
             * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
             * @public
             * @override
             */
            init: function () {
                // call the base component's init function
                UIComponent.prototype.init.apply(this, arguments);
    
                // enable routing
                this.getRouter().initialize();
    
                // set the device model
                this.setModel(models.createDeviceModel(), "device");
    
    
            }
        });
    });

    Here, the model file location is added at the top as “YRR/YRR/model/models” and thereafter in the end the default model is configured using this ” this.setModel(models.createDeviceModel(), “device”);”

    We need to add one more configuration, for our model with this code: “this.setModel(models.createAppConfigModel(), “AppConfig”);”

    Now, the code will look like this:

    sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/Device",
        "YRR/YRR/model/models"
    ], function (UIComponent, Device, models) {
        "use strict";
    
        return UIComponent.extend("YRR.YRR.Component", {
    
            metadata: {
                manifest: "json"
            },
    
            /**
             * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
             * @public
             * @override
             */
            init: function () {
                // call the base component's init function
                UIComponent.prototype.init.apply(this, arguments);
    
                // enable routing
                this.getRouter().initialize();
    
                // set the device model
                this.setModel(models.createDeviceModel(), "device");
    
                // set the app Config model
                this.setModel(models.createAppConfigModel(), "AppConfig");
    
            }
        });
    });

    That’s it, and we have a global model now.

    3. Using the model in view or Controller

    Now, we can easily access the model in view and controller. Also, we can manipulate the model from the controller.

    How to fetch and change values of a Global Model in SAP UI5?

    To fetch a global model, we need to call the model configuration with the model name we want to access or modify. Let’s assume you need to access the model “count” whose initial value is set as 0.

    var localCount = this.getOwnerComponent().getModel("AppConfig").getProperty("/count");

    The variable “localCount” will now have the value of 0.

    To change the value, we need to call the model configuration with the model name we want to modify. Let’s assume you need to modify the model “count” with a new value as 90.

    this.getOwnerComponent().getModel("AppConfig").setProperty("/count", 90);
    

    In the above step, we have updated the value of the count in the global model.

    How to use Global Model to send values from one page to another?

    To send values from one page to another, you need to perform these steps:

    1. Create a field in the global model that will be used to transfer data

    2. Update the value of the model on the first page, then navigate to the second page

    3. On the second page, get the value of the model

    All these steps are already discussed above in different sections.

    How to bind the global model directly to View?

    To bind a global model directly to the view, you need to perform the following as per the given use cases:

    1. Bind Global Model to a Button Text

    <Button icon="sap-icon://accept" visible="true" text="{AppConfig>/ButtonText}" 
    type="Accept" class="sapUiTinyMarginEnd" press="onAccept"/>

    In this example, we have assumed that the ButtonText is a field in the model having the text value of Button.

    2. Bind Global Model to the visibility of a button

    <Button visible="{=${AppConfig>/OrderType} === 'PO Release' ? true : false}" text="Okay" press="onReleasePO"/>
    <Button visible="{=${AppConfig>/OrderType} === 'Cancel PO Release' ? true : false}" text="Okay" press="onCancelReleasePO"/>

    In this example, Button 1 gets visible if the OrderType has the value ‘PO Release’, else becomes invisible.
    And Button 2 gets visible if the OrderType has the value ‘Cancel PO Release’, else becomes invisible.
    In this way, we can control the visibility of a button based on OrderType with the help of the Global Model.

    3. Bind Global Model to a table [if Model is JSON]

    It is important to have the Model that is being planned to bind with a table to have a format as below:

    {results: [{<JSON Data>}]};

    It means if your model has just an array of data in this form: [{<JSON Data>}] or {“results”: {JSON Data}}
    in both cases, the model binding will fail.

    Controller Code:

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
    
            },
    
            onBeforeRendering: function () {
                var that = this;
                var val = {
                    country_code: 1,
                    country_text: "India"
                };
                var aData = [];
                aData.push(val);
                that.getOwnerComponent().getModel("AppConfig").setProperty("/tableData", {
                    "results": aData
                });
            }
        });
    });

    View Code:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Table Binding">
                        <content>
                            <Table id="idTable" items="{AppConfig>/tableData/results}">
                                <columns>
                                    <Column><Text text="Country Code"/></Column>
                                    <Column><Text text="Country Text"/></Column>
                                </columns>
                                <items>
                                    <ColumnListItem>
                                        <cells>
                                            <Text text="{AppConfig>country_code}"/>
                                            <Text text="{AppConfig>country_text}"/>
                                        </cells>
                                    </ColumnListItem>
                                </items>
                            </Table>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    Output:

    Bind Global Model to a table

    4. Bind Global Model to a drop-down [if Model is JSON]

    This process is very much similar to the table code (in the above step). We will use the same controller code but change the view code.

    Controller Code:

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
    
            },
    
            onBeforeRendering: function () {
                var that = this;
                var val1 = {
                    country_code: 1,
                    country_text: "India"
                };
                var val2 = {
                    country_code: 2,
                    country_text: "Germany"
                };
                var aData = [];
                aData.push(val1);
                aData.push(val2);
                that.getOwnerComponent().getModel("AppConfig").setProperty("/tableData", {
                    "results": aData
                });
            }
        });
    });

     

    View Code:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Select a Drop Down">
                        <content>
                            <Select id="idCountrySelect" width="90%" showSecondaryValues="true" items="{AppConfig>/tableData/results}">
                                <core:ListItem key="{AppConfig>country_code}" text="{AppConfig>country_text}"/>
                            </Select>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    Output:

    Bind Global Model to a drop-down [if Model is JSON]

    5. Bind Global Model to a form [if Model is an Object]

    The right way to bind a model to a form should be JSON Model binding with the form with the help of form ID. In this example, we will be binding directly with the global model.

    Controller:

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
    
            },
    
            onBeforeRendering: function () {
                var val = {
                    fname: "Rudramani",
                    lname: "Pandey",
                    country: "India",
                    phone: "+91-9999099099"
                };
                this.getOwnerComponent().getModel("AppConfig").setProperty("/formData", val);
            }
        });
    });

     

    View:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Form Binding">
                        <content>
                            <f:SimpleForm id="idSFormPlatesOvp" editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" labelSpanL="4" labelSpanM="4"
                                labelSpanS="12" adjustLabelSpan="false" emptySpanXL="0" emptySpanL="0" emptySpanM="0" emptySpanS="0" columnsXL="3" columnsL="1" columnsM="1"
                                singleContainerFullSize="false">
                                <f:content>
                                    <core:Title text="Basic Info"/>
                                    <Label text="First Name"/>
                                    <Text text="{AppConfig>/formData/fname}"/>
                                    <Label text="Last Name"/>
                                    <Text text="{AppConfig>/formData/lname}"/>
                                    <Label text="Country"/>
                                    <Text text="{AppConfig>/formData/country}"/>
                                    <Label text="Mobile"/>
                                    <Text text="{AppConfig>/formData/phone}"/>
                                </f:content>
                            </f:SimpleForm>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Output:

    Bind Global Model to a form [if Model is an Object]

    6. Bind Global Model to a text [if Model is an Object]

    It will be exactly like the above. In case you are binding directly with a field then binding will be like:

    <Text text="{AppConfig>/phone}"/>

    In case you are binding the text with an object, and then you need to reach up to your field using ‘/’, like:

    <Text text="{AppConfig>/formData/phone}"/>

     

    7. Changing the Visibility of fields using the Global Model

    In this example, you can use Global Model to change the visibility of multiple fields. This example is exactly similar to Example 2.

    We will just add a condition to the above form, within the view:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Form Binding">
                        <content>
                            <f:SimpleForm id="idSFormPlatesOvp" editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" labelSpanL="4" labelSpanM="4"
                                labelSpanS="12" adjustLabelSpan="false" emptySpanXL="0" emptySpanL="0" emptySpanM="0" emptySpanS="0" columnsXL="3" columnsL="1" columnsM="1"
                                singleContainerFullSize="false">
                                <f:content>
                                    <core:Title text="Basic Info"/>
                                    <Label text="First Name"/>
                                    <Text text="{AppConfig>/formData/fname}"/>
                                    <Label text="Last Name"/>
                                    <Text text="{AppConfig>/formData/lname}"/>
                                    <Label text="Country"/>
                                    <Text visible="{=${AppConfig>/visible} === true ? true : false}" text="{AppConfig>/formData/country}"/>
                                    <Label text="Mobile"/>
                                    <Text visible="{=${AppConfig>/visible} === true ? true : false}" text="{AppConfig>/formData/phone}"/>
                                </f:content>
                            </f:SimpleForm>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    In case we make the global model field “visible” as true, then the form will load as usual:

    Bind Global Model to a form [if Model is an Object]

    In case, we will make it false, as shown below:

    sap.ui.define([
        "sap/ui/model/json/JSONModel",
        "sap/ui/Device"
    ], function (JSONModel, Device) {
        "use strict";
    
        return {
    
            createDeviceModel: function () {
                var oModel = new JSONModel(Device);
                oModel.setDefaultBindingMode("OneWay");
                return oModel;
            }, //app Congiguration model 
            createAppConfigModel: function () {
                var AppConfig = {
                    "editable": false,
                    "count": 0,
                    "formData": {},
                    "tableData": {},
                    "visible": false
                };
                var oModel = new JSONModel(AppConfig);
                return oModel;
            }
    
        };
    });

    Then the visibility of these two fields will be turned off:

    Changing the Visibility of fields using the Global Model

    In order to change the value of the global field “visible”, we will write the following code in the controller:

    this.getOwnerComponent().getModel("AppConfig").setProperty("/vsible", false);

     

    8. Making a form Editable and Non-Editable using the Global Model

    To toggle the form Editable and Non-editable, we add a field “editable” in the model, then change the same in the controller based upon the current state [if true, then change it to false and vice-versa] and thereafter bind the same in the editable field.

    Model File:

    sap.ui.define([
        "sap/ui/model/json/JSONModel",
        "sap/ui/Device"
    ], function (JSONModel, Device) {
        "use strict";
    
        return {
    
            createDeviceModel: function () {
                var oModel = new JSONModel(Device);
                oModel.setDefaultBindingMode("OneWay");
                return oModel;
            }, //app Congiguration model 
            createAppConfigModel: function () {
                var AppConfig = {
                    "editable": false,
                    "count": 0,
                    "formData": {},
                    "tableData": {},
                    "visible": false
                };
                var oModel = new JSONModel(AppConfig);
                return oModel;
            }
    
        };
    });

    Controller File:

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
    
            },
    
            onPressToggle: function () {
                var editable = this.getOwnerComponent().getModel("AppConfig").getProperty("/editable");
                if (editable) {
                    this.getOwnerComponent().getModel("AppConfig").setProperty("/editable", false);
                } else {
                    this.getOwnerComponent().getModel("AppConfig").setProperty("/editable", true);
                }
            }
        });
    });

    View File:

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core"
        xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Form Binding">
                        <content>
                            <VBox>
                                <Button text="Toggle Visibilty" press="onPressToggle"/>
                            <f:SimpleForm id="idSFormPlatesOvp" editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" labelSpanL="4" labelSpanM="4"
                                labelSpanS="12" adjustLabelSpan="false" emptySpanXL="0" emptySpanL="0" emptySpanM="0" emptySpanS="0" columnsXL="3" columnsL="1" columnsM="1"
                                singleContainerFullSize="false">
                                <f:content>
                                    <core:Title text="Basic Info"/>
                                    <Label text="First Name"/>
                                    <Input editable="{=${AppConfig>/editable} === true ? true : false}" value="{AppConfig>/formData/fname}"/>
                                    <Label text="Last Name"/>
                                    <Input editable="{=${AppConfig>/editable} === true ? true : false}" value="{AppConfig>/formData/lname}"/>
                                    <Label text="Country"/>
                                    <Input editable="{=${AppConfig>/editable} === true ? true : false}" value="{AppConfig>/formData/country}"/>
                                    <Label text="Mobile"/>
                                    <Input editable="{=${AppConfig>/editable} === true ? true : false}" value="{AppConfig>/formData/phone}"/>
                                </f:content>
                            </f:SimpleForm>
                            </VBox>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

  • Using formatter.js in SAP UI5 (In View and Controller)

    Preface – This post is part of the UI5 Programs series.

    What is a formatter in UI5?

    A formatter in UI5 is a model that is created to store functions. Each function is used to format the data into a specific format. Generally, it is used to perform the following:

    • Format Data to a specific type (dd/mm/yyyy or something else)
    • Convert values from single character [‘X’, ”] to [Yes, No]
    • Convert values from single characters to icons
    • Format timestamp and time (DD.MM.YYYY:HH:MM:SS)
    • Format Decimal (from 3 decimals to 2 decimals)
    • Remove Decimal Zero (All zeroes after Decimal)
    • Remove leading zeroes from the number

    Guidelines for using formatter

    Formatter is treated just like another function and thus has the same guidelines that are followed by other functions:

    1. A formatter should always return something back
    2. A formatter should have preconditions to fail-safe the formating
    3. A formatter should not return invalid data that can dump the View binding
    4. A formatter should use i18n for all its hard-coded texts
    5. A formatter should be placed in the Model folder with the name “formatter.js”
    6. A formatter should have comments before every function determining the input parameters and output data information

    A blank formatter looks something like this:

    sap.ui.define([], function() {
        "use strict";
    
        return {
    // All your formatted functions like below
    /**
    * Returns Timestamp 
     * @public
     * @param {string} sValue the number string to be timestamp formatted
    * @returns {string} sValue in DD-MM-YYYY: HH:MM:SS
    */
    timestampUnit: function(sValue) {
                if (!sValue) {
                    return "";
                }
                var timestamp = new Date(sValue.seconds * 1000);
                return timestamp;
    },
    
        };
    
    });

     

    Making formatter Global to the Entire App

    To make your formatter Global to the entire app, you need to add it to the BaseController.js file. This will make it accessible to all other pages.

    Adding formatter in Controller

    To add a formatter to a controller file, you need to add it in the definition part and then make the field formatter global. The code is as below:

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "YRR/YRR/model/formatter",
    ], function (Controller, formatter,
        ) {
        "use strict";
    
        return BaseController.extend("YRR.YRR.controller.Main", {
    
            formatter: formatter,
            onInit: function () {
    
                                        }
        });
    });

    In the above code, you can see we defined the formatter and specified the exact location. And then, just above the onInit function, we have reassigned it to a global field.

    Using formatter in Controller

    Formatter functions are just like other functions and can be called or initiated with ‘this’ keywords.

    this.formatter.getLocalTime(<pass your field here>)

    In the above statement, this.formatter will call the formatter file. getLocalTime is the name of the function. <pass your fields here> is the placeholder for all the fields that your function ‘getLocalTime’ requires.

    Using formatter in View

    Passing one value in formatter

    To pass a single value in formatter, we replace the text binding with formatter binding, as shown below:

    <Text text="{ path : 'LineItem', formatter: '.formatter.removeZero' }"/>

    In the above code, the path is the field name that is used for binding. And the formatter has the name of the formatter file followed by the function name.

    Passing multiple values in formatter

    <Text text="{ parts : [{path: 'OrdQty'},{path: 'QtyConversion'}], formatter: '.formatter.calculateMultiply' }"/>
    

    In the above code, we have passed multiple values into our formatter using the object ‘parts’ which itself has multiple objects in the form of {path: ‘<field name>’}

    Examples of Formatter

    1. Get Local Time

    getLocalTime: function(sValue) {
                if (sValue) {
                    var dateString = sValue;
                    var year = +dateString.substring(0, 4);
                    var month = +dateString.substring(4, 6);
                    var day = +dateString.substring(6, 8);
                    var date = new Date(year, month - 1, day);
                    var months = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
                    var todate = date.getDate();
                    var tomonth = date.getMonth();
                    var monthText = months[tomonth];
                    var toyear = date.getFullYear();
                    if (month < 10 && month > 0) {
                        month = '0' + month.toString();
                    }
                    if (todate < 10 && todate > 0) {
                        todate = '0' + todate.toString();
                    }
                    var original_date = todate + '.' + month + '.' + toyear;
                    if (original_date == '30.0.1899') {
                        return '';
                    } else {
                        return original_date;
                    }
                } else {
                    return "";
                }
            }

    2. Remove Leading Zeros

    removeZero: function(sValue) {
        if (sValue) {
            sValue = sValue.replace(/^0+/, '');
            return sValue;
        } else {
            return '';
        }
    }

    3. Remove Decimal Zeros

    removedecimalZero: function(sValue) {
        if (sValue) {
            sValue = parseInt(sValue);
            sValue = sValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
            if (sValue == '0') {
                return '0';
            } else {
                return sValue;
            }
    
        } else {
            return '0';
        }
    }

    4. Format Decimal Numbers

    formatDecimal: function(sValue) {
        if (sValue) {
            if (sValue == '0.000') {
                return '';
            } else {
                sValue = parseFloat(sValue).toFixed(2);
                return sValue;
            }
    
        } else {
            return '';
        }
    }

    5. Format Custom Icons

    customIcon: function(sValue) {
        if (sValue === "X") {
            return 'sap-icon://message-success';
        } else {
            return '';
        }
    }

    6. Formatting Currency

    This formatting is for adding commas ‘,’ as per currency type, and adding currency signs with numbers.

    currency: function(sValue) {
        if (sValue) {
            // Create our number formatter.
            var formatter = new Intl.NumberFormat('en-US', {
                style: 'currency',
                currency: 'SAR'
            });
    
            return (formatter.format(sValue)); /* $2,500.00 */
        } else {
            return '';
        }
    },

    7. Rounding a Number

    roundNum: function(sValue) {
            if (sValue) {
                sValue = parseFloat(sValue).toFixed(2);
                sValue = Math.round(sValue);
                sValue = sValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
                return sValue;
            } else {
                return '';
            }
        },

     

  • Using i18n.properties in SAP UI5 (View, Controller, Adding comment in i18n)

    Preface – This post is part of the UI5 Programs series.

    What is i18n?

    i18n, which stands for internationalization, are Translatable Texts, all in a single place. It means a developer should keep all the texts of their app within i18n so that, in case it is required to have another version of the app with a different language, then all together, a copy of i18n can be made, and those texts can be converted into another language at once.

    Suppose you have only one version that too in English; then you just need a single i18n file. In case you have multiple languages like English (Britsh and US separate), German and French. Then you will need to have these i18n files:

    • i18n.properties [default]
    • i18n_en.properties [for English – British]
    • i18n_en_US.properties [for English – US]
    • i18n_de.properties [for German]
    • i18n_fr.properties [for French]

    Once you create these files, you need to add them in Manifest as a resource bundle. Then, within a controller, you need to use them as per the language of the browser. You can also provide your own language switcher drop-down like this:

    Language Switcher

    In case the app is deployed over Fiori, and then you can take the language set within Fiori:

    Fiori Language Settings

    Guidelines of writing i18n

    You can write the entire i18n file in the form of key= value as shown below, where the key will be then added overview and controller, and the value will be the one shown over UI.

    title=Admin Panel
    appTitle=Admin Panel
    appDescription=Admin Panel for SAP
    id=User ID
    pass=Password
    version=Ver 2.3.0

    Which will look like this in the code editor:

    i18n sample

    But, SAP UI5 suggests the following as the guidelines for writing i18n in a correct and standardized way:

    1. All the keys should be written in a lowercase
    2. The values of i18n can contain parameters like {0}, {1}, {2}, … [This can be used for special dynamic conditions]
    3. For special characters, use Unicode escape sequences
    4. Add comments using ‘#’ before sets of texts that are for certain category like:
      #XMSG: title of App
      title=Admin App
      appTitle=Admin App
      appDescription=Admin App
      
      #XMSG: App Version for Local Use
      appVersion=Version 2.0.14
      
      #XMSG: Not Found texts
      NotFound=Not Found
      NotFound.text=Sorry, but the requested resource is not available.
      NotFound.description=Please check the URL and try again.
      noDataDescriptiont=No data found. Try adjusting the filter settings or check your service.
      
      #XFLD: Form Texts
      COUNTRY=Country
      ServiceType=Service Type
      InOut=Inbound/Outbound
      GroupID=Group ID
      In=Inbound
      Out=Outbound
      

       

    Adding i18n in Manifest File

    Majorly, i18n is preconfigured within the manifest file. Anyhow, you can configure like shown below [it will be within “sap.ui5” object]:

    "models": {
        "i18n": {
            "type": "sap.ui.model.resource.ResourceModel",
            "settings": {
                "bundleName": "YRR.YRR.i18n.i18n"
            }
        }
    }

     

    Using i18n in View

    To use i18n in UI5 View (once it is already set as above in the manifest file), you need to just specify the value in the i18n file and use it for texts using the named model call, i.e. {i18n>text} where text is the key in i18n file with a value against it, like text = This is a text.

    To understand better, we will specify everything in different sections and showcase the output:

    i18n Content

    title=Admin Panel
    appTitle=YRR
    appDescription=App Description
    id=User ID
    pass=Password
    fieldsMandatory=All the fields are mandatory.
    version=Ver 2.3.0

    View Content

    <tnt:header>
    <tnt:ToolHeader>
    <Button id="sideNavigationToggleButton" icon="sap-icon://menu2" type="Transparent" press="onCollapseExpandPress">
    <layoutData>
    <OverflowToolbarLayoutData priority="NeverOverflow"/>
    </layoutData>
    </Button>
    <ToolbarSpacer/>
    <core:Icon src="sap-icon://vehicle-repair"></core:Icon>
    <Text text="{i18n>title}" wrapping="false">
    <layoutData>
    <OverflowToolbarLayoutData priority="Disappear"/>
    </layoutData>
    </Text>
    <ToolbarSpacer/>
    <Button text="Download User Excel" icon="sap-icon://excel-attachment" type="Transparent" press="onSelectExtendedUser"/>
    <Text text="{i18n>version}" wrapping="false"/>
    <!--<Button icon="sap-icon://bell" press="handleMessagePopoverPress"/>-->
    </tnt:ToolHeader>
    </tnt:header>

    Output

    i18n Example

    As you can see, we have binded the title and version with i18n, but the button text ‘Download Excel’ is hardcoded.

    Using i18n in Controller

    To get i18n data in View, you can use the global model that was specified within the manifest. For Controller too, we fetch the same model. You can either fetch everytime you need it, or make it global for that controller by specifying the following within onInit function:

    // Bundle for i18n 
    this.oBundle = this.getOwnerComponent().getModel("i18n").getResourceBundle();

    Once you have specified the above

    Showing Message from i18n in MessageBox

    Now, we will use the above bundle to fetch a text from our i18n:

    // read msg from i18n model
    sMsg = that.oBundle.getText("fieldsMandatory");
    MessageBox.error(sMsg);

    Now, the MessageBox will load the message from i18n, and you don’t have to hardcode the text within the controller.

    Messagebox message from i18n

     

  • Master Detail with multiple fragments for detail and single controller in SAP UI5

    Preface – This post is part of the UI5 Programs series.

    In this article, we will learn Master Detail with multiple fragments for detail and a single controller in SAP UI5. Visit this page, in case you are looking for Master Detail with multiple views and multiple controllers for detail

    Master Detail with multiple fragments for detail and single controller in SAP UI5

    Main.view.xml

    In this use case, our Application name is YRR. We have used tnt:ToolPage to create Master and Detail sections. Within detail, you will see multiple fragments within ScrollContainer. All the tab names are specified within tnt:Side Navigation. On click of these tabs, their functions are called which navigates the view with the help of Scroll Containers ID.

    <mvc:View xmlns:core="sap.ui.core" controllerName="YRR.YRR.controller.Main" xmlns:mvc="sap.ui.core.mvc" xmlns:tnt="sap.tnt"
        xmlns:html="http://www.w3.org/1999/xhtml" displayBlock="true" xmlns="sap.m"
        xmlns:custom="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1">
        <!--<App id="idAppControl">-->
        <tnt:ToolPage id="toolPage">
            <tnt:header>
                <tnt:ToolHeader>
                    <Button id="sideNavigationToggleButton" icon="sap-icon://menu2" type="Transparent" press="onCollapseExpandPress">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow"/>
                        </layoutData>
                    </Button>
                    <ToolbarSpacer/>
                    <core:Icon src="sap-icon://vehicle-repair"></core:Icon>
                    <Text text="{i18n>title}" wrapping="false">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="Disappear"/>
                        </layoutData>
                    </Text>
                    <ToolbarSpacer/>
                    <Button text="Download User Excel" icon="sap-icon://excel-attachment" type="Transparent" press="onSelectExtendedUser"/>
                    <Text text="{i18n>version}" wrapping="false"/>
                    <!--<Button icon="sap-icon://bell" press="handleMessagePopoverPress"/>-->
                </tnt:ToolHeader>
            </tnt:header>
            <tnt:sideContent>
                <tnt:SideNavigation expanded="true" selectedKey="root0">
                    <tnt:NavigationList>
                        <tnt:NavigationListItem text="Users" key="root0" icon="sap-icon://account" expanded="true" select="onSelectUser"/>
                        <!--<tnt:NavigationListItem text="Download User Excel" key="root1" icon="sap-icon://excel-attachment" expanded="true"-->
                        <!--	select="onSelectExtendedUser"/>-->
                        <tnt:NavigationListItem text="Insurance" key="root2" icon="sap-icon://insurance-car" expanded="true" select="onSelectInsurance"/>
                        <tnt:NavigationListItem text="Transactions" key="root3" icon="sap-icon://vehicle-repair" expanded="true" select="onSelectTransactions"/>
                        <tnt:NavigationListItem text="Controller &amp; Driver" key="root4" icon="sap-icon://manager" expanded="true" select="onSelectController"/>
                        <tnt:NavigationListItem text="Car Plates" key="root5" icon="sap-icon://add-contact" expanded="true" select="onSelectCarPlates"/>
                        <tnt:NavigationListItem text="Promotion &amp; Rewards" icon="sap-icon://loan" expanded="false">
                            <tnt:NavigationListItem text="Promotion" key="root6" icon="sap-icon://payment-approval" expanded="true" select="onSelectPromotion"/>
                            <tnt:NavigationListItem text="Rewards" key="root7" icon="sap-icon://loan" expanded="true" select="onSelectRewards"/>
                            <tnt:NavigationListItem text="Specific Rewards" key="root7_1" icon="sap-icon://loan" expanded="true" select="onSelectSpecificRewards"/>
                        </tnt:NavigationListItem>
                        <tnt:NavigationListItem text="Notifications" icon="sap-icon://sales-notification" expanded="false">
                            <tnt:NavigationListItem text="App Notification" key="root8" icon="sap-icon://sales-notification" expanded="true"
                                select="onSelectNotification"/>
                            <tnt:NavigationListItem text="Manual Push Notification" key="root8_1" icon="sap-icon://sales-notification" expanded="true"
                                select="onSelectPushNotification"/>
                        </tnt:NavigationListItem>
                        <tnt:NavigationListItem text="Home Images" icon="sap-icon://background" expanded="false">
                            <tnt:NavigationListItem text="Promo Images" key="root9_1" icon="sap-icon://background" expanded="true" select="onSelectPromoImages"/>
                            <tnt:NavigationListItem text="Dashboard Images" key="root9_2" icon="sap-icon://background" expanded="true" select="onSelectDashboardImages"/>
                            <tnt:NavigationListItem text="Dashboard Icons" key="root9_3" icon="sap-icon://background" expanded="true" select="onSelectDashboardIcons"/>
                        </tnt:NavigationListItem>
                        <tnt:NavigationListItem text="Master Data" icon="sap-icon://accounting-document-verification" expanded="false">
                            <tnt:NavigationListItem text="Terms &amp; Conditions" key="root12" icon="sap-icon://activities" expanded="true" select="onSelectTerms"/>
                            <tnt:NavigationListItem text="Car Brands" key="root10" icon="sap-icon://insurance-car" expanded="true" select="onSelectCarBrands"/>
                            <tnt:NavigationListItem text="Organizations" key="root13" icon="sap-icon://insurance-car" expanded="true" select="onSelectOrg"/>
                        </tnt:NavigationListItem>
                        <tnt:NavigationListItem text="Enquiry" key="root11" icon="sap-icon://headset" expanded="true" select="onSelectInquiry"/>
                    </tnt:NavigationList>
                    <tnt:fixedItem>
                        <tnt:NavigationList >
                            <tnt:NavigationListItem text="Log Out" icon="sap-icon://log" select="onSelectLogOut"/>
                        </tnt:NavigationList>
                    </tnt:fixedItem>
                </tnt:SideNavigation>
            </tnt:sideContent>
            <tnt:mainContents>
                <NavContainer id="pageContainer" initialPage="root1">
                    <pages>
                        <ScrollContainer id="root0" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.UserDetails" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.ExtendedUserDetails" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root1_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.UserOvp" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root2" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.InsuranceDetails" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root2_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.InsuranceOvp" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root3" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Transaction" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root4" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Controller" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root5" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.CarPlates" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root5_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.CarPlatesOvp" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root6" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Promotion" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root7" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Rewards" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root7_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.SpecificRewards" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root8" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Notification" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root8_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.PushNotification" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root9_1" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.PromoImages" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root9_2" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.HomeImages" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root9_3" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.DashboardIcons" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root10" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.CarDetails" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root11" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Inquiry" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root12" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.TermsConditions" type="XML"/>
                        </ScrollContainer>
                        <ScrollContainer id="root13" horizontal="false" vertical="true" height="100%">
                            <core:Fragment fragmentName="YRR.YRR.fragment.Organizations" type="XML"/>
                        </ScrollContainer>
                    </pages>
                </NavContainer>
            </tnt:mainContents>
        </tnt:ToolPage>
        <!--</App>-->
    </mvc:View>

    Output of tnt:SideNavigation:

    Content of Side Navigation

    Main.controller.js

    // the function used to show the User Fragment
    onSelectUser: function (oEvent) {
    // "pageContainer" is the ID of NavContainer within which all the ScrollContainer are added
    // "root0" is the ID of first ScrollContainer within which we have a fragment called "UserDetails"
                this.byId("pageContainer").to(this.getView().createId("root0"));
        },
    
    
    

    No special navigation handling is required within the Manifest file.

    Fragment: UserDetails.fragment.xml

    This Fragment will open when onSelectUser is clicked.

    <core:FragmentDefinition xmlns="sap.m" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core"
        xmlns:u="sap.ui.unified" xmlns:commons="sap.suite.ui.commons">
        <OverflowToolbar>
            <Title text="User Data ({AppConfig>/UserCount})" level="H2"/>
            <ToolbarSpacer/>
            <Button text="Sort" icon="sap-icon://sort" press="handleUserSort"/>
        </OverflowToolbar>
        <Table id="idUserTable" inset="false" items="{/Users}" sticky="ColumnHeaders,HeaderToolbar" class="sapFDynamicPageAlignContent" width="auto">
            <headerToolbar>
                <OverflowToolbar>
                    <SearchField id="idSearchUserName" placeholder="Search Name" value="" search="onSearchName" width="15rem"/>
                    <SearchField id="idSearchUserPhone" placeholder="Search Phone Number" value="" search="onSearchPhone" width="15rem"/>
                    <SearchField id="idSearchUserEmail" placeholder="Search Email ID" value="" search="onSearchUser" width="15rem"/>
                    <SearchField id="idSearchUserOrg" placeholder="Search Organization" value="" search="onSearchOrg" width="15rem"/>
                </OverflowToolbar>
            </headerToolbar>
            <columns>
                <Column minScreenWidth="Tablet" demandPopin="true">
                    <Text text="User Name"/>
                </Column>
                <Column minScreenWidth="Desktop" demandPopin="true" hAlign="End">
                    <Text text="Email ID"/>
                </Column>
                <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                    <Text text="Phone Number"/>
                </Column>
                <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                    <Text text="Date of Birth"/>
                </Column>
                <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                    <Text text="Organization"/>
                </Column>
            </columns>
            <items>
                <ColumnListItem type="Navigation" press="onUserPress">
                    <customData>
                        <core:CustomData key="idUserTable"/>
                    </customData>
                    <cells>
                        <Text text="{userName}"/>
                        <Text text="{email}"/>
                        <Text text="{mob}"/>
                        <Text text="{ path: 'dob', formatter: '.formatter.dateUnit' }"/>
                        <Text text="{org}"/>
                        <!--<Select id="iduserRole" selectedKey="{userRole}" change="onSelectUserRole">-->
                        <!--	<core:Item key="BASIC" text="BASIC"/>-->
                        <!--	<core:Item key="SG Member" text="SG Member"/>-->
                        <!--	<core:Item key="SGMY Member" text="SGMY Member"/>-->
                        <!--</Select>-->
                    </cells>
                </ColumnListItem>
            </items>
        </Table>
        <Bar design="SubHeader" id="idLoadMore">
            <contentMiddle>
                <VBox height="100%" alignItems="Center">
                    <Button text="Load Next 20 Data >>" press="onMoreUsers"/>
                </VBox>
            </contentMiddle>
            <contentRight>
                <Input type="Number" id="pageNumber" width="50px"></Input>
                <Button id="goToButton" text="Go to" type="Emphasized" press="onHandleGoTo"></Button>
            </contentRight>
        </Bar>
        <VBox id="idLoadSortMore" height="100%" alignItems="Center" visible="false">
            <Button text="Load Next 20 Data >>" press="onMoreSortUsers"/>
        </VBox>
    </core:FragmentDefinition>

    Output of Fragment:

    Content of Fragment

  • Master Detail with multiple views and multiple controllers for detail in SAP UI5

    Preface – This post is part of the UI5 Programs series.

    In this article, we will discuss Master Detail with multiple views and multiple controllers for detail in SAP UI5. Visit this page, in case you are looking for Master Detail with multiple fragments for detail and a single controller.

    Master Detail with multiple views and multiple controllers for detail in SAP UI5

    App.view.xml

    The UI5 App name in our use case is “admin”.

    <mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
        controllerName="admin.admin.controller.App" xmlns:html="http://www.w3.org/1999/xhtml">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <!--Split App to Enable Master Detail Configuration-->
                    <SplitApp id="Splitapp" mode="HideMode"></SplitApp> 
                   // delete mode if you wan't to always show the Master section
                </pages>
            </App>
        </Shell>
    </mvc:View>

    App.controller.js

    Nothing is to be written App.Controller.js file

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("admin.admin.controller.App", {
    
            onInit: function () {
    
            }
        });
    
    });

    Manifest.json

    1. Change the rootView to App

    "rootView": {
                "viewName": "admin.admin.view.App",
                "type": "XML",
                "async": true,
                "id": "app"
            },

    2. Update the Routing configuration

    "routing": {
                "config": {
                    "routerClass": "sap.m.routing.Router",
                    "viewType": "XML",
                    "async": true,
                    "viewPath": "admin.admin.view",
                    "controlId": "app",
                    "clearControlAggregation": false
                },
                "routes": [{
                    "name": "Login",
                    "pattern": "",
                    "target": [
                        "masterTarget",
                        "Login"
                    ]
                }, {
                    "name": "Dashboard",
                    "pattern": "Dashboard",
                    "target": [
                        "masterTarget",
                        "Dashboard"
                    ]
                }, {
                    "name": "Appointments",
                    "pattern": "Appointments",
                    "target": [
                        "masterTarget",
                        "Appointments"
                    ]
                }, {
                    "name": "Doctors",
                    "pattern": "Doctors",
                    "target": [
                        "masterTarget",
                        "Doctors"
                    ]
                }, {
                    "name": "Patient",
                    "pattern": "Patient",
                    "target": [
                        "masterTarget",
                        "Patient"
                    ]
                }, {
                    "name": "Subscription",
                    "pattern": "Subscription",
                    "target": [
                        "masterTarget",
                        "Subscription"
                    ]
                }, {
                    "name": "Symptoms",
                    "pattern": "Symptoms",
                    "target": [
                        "masterTarget",
                        "Symptoms"
                    ]
                }, {
                    "name": "Specialty",
                    "pattern": "Specialty",
                    "target": [
                        "masterTarget",
                        "Specialty"
                    ]
                }, {
                    "name": "Tests",
                    "pattern": "Tests",
                    "target": [
                        "masterTarget",
                        "Tests"
                    ]
                }, {
                    "name": "Support",
                    "pattern": "Support",
                    "target": [
                        "masterTarget",
                        "Support"
                    ]
                }],
                "targets": {
                    "masterTarget": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "masterPages",
                        "viewId": "idMaster",
                        "viewName": "Master",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Login": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "Login",
                        "viewName": "Login",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Dashboard": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idDashboard",
                        "viewName": "Dashboard",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Appointments": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idAppointments",
                        "viewName": "Appointments",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Doctors": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idDoctors",
                        "viewName": "Doctors",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Patient": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idPatient",
                        "viewName": "Patient",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Subscription": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idSubscription",
                        "viewName": "Subscription",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Symptoms": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idSymptoms",
                        "viewName": "Symptoms",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Specialty": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idSpecialty",
                        "viewName": "Specialty",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Tests": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idTests",
                        "viewName": "Tests",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    },
                    "Support": {
                        "viewType": "XML",
                        "transition": "slide",
                        "controlAggregation": "detailPages",
                        "viewId": "idSupport",
                        "viewName": "Support",
                        "viewLevel": 1,
                        "controlId": "Splitapp"
                    }
                }
            }

    As you can see we have multiple detail page, and a common thing among all is “masterTarget”. This is the target for Master Page, i.e. “The left pane where you can have multiple tabs to switch pages”.

    Master Page View:  Master.view.xml

    <mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"  xmlns:tnt="sap.tnt"
        controllerName="admin.admin.controller.Master" xmlns:html="http://www.w3.org/1999/xhtml">
        <Page id="master" title="{i18n>Actions}" backgroundDesign="List" class="sapUiStdPage">
            <!--All Master Pane tabs are maintained here-->
            <tnt:NavigationList id="navigationList" selectedKey="Tab_1" itemSelect="onListItemPress">
                <tnt:NavigationListItem text="Configuration" icon="sap-icon://overview-chart" key="Dashboard"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Appointments" icon="sap-icon://account" key="Appointments"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Doctors" icon="sap-icon://stethoscope" key="Doctors"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Patient" icon="sap-icon://wounds-doc" key="Patient"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Subscription" icon="sap-icon://collections-insight" key="Subscription"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Symptoms" icon="sap-icon://electrocardiogram" key="Symptoms"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Medical Specialty" icon="sap-icon://clinical-order" key="Specialty"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Tests" icon="sap-icon://clinical-tast-tracker" key="Tests"></tnt:NavigationListItem>
                <tnt:NavigationListItem text="Support" icon="sap-icon://headset" key="Support"></tnt:NavigationListItem>
                <!--<tnt:NavigationListItem text="Log Out" icon="sap-icon://log" key="LogOut"></tnt:NavigationListItem>-->
            </tnt:NavigationList>
            <footer>
                <OverflowToolbar>
                    <Text text="{i18n>appVersion}"/>
                    <ToolbarSpacer/>
                </OverflowToolbar>
            </footer>
        </Page>
    </mvc:View>

    Master Controller: Master.controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("admin.admin.controller.Master", {
    
            /**
             * Called when a controller is instantiated and its View controls (if available) are already created.
             * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
             * @memberOf Healthbridge-admin.Healthbridge-admin.view.Master
             */
            onInit: function () {
                // Get Router Info
                this.oRouter = this.getOwnerComponent().getRouter();
            },
            /**
             * onListItemPress is invoked on click from UI. 
             * Input: Key Maintained in Master View
             * Output: Navigation to the Master Page
             */
            onListItemPress: function (oEvent) {
                var that = this;
                sap.ui.core.BusyIndicator.show();
                // var sTimeOutErrorMsg = this.oBundle.getText("TimeOutError");
                var sError;
                var sToPageId = oEvent.getParameter("item").getKey();
                if (sToPageId) {
                    try {
                        that.oRouter.navTo(sToPageId);
                    } catch (err) {
                        if (err.statusCode === 401) {
                            // sError = sTimeOutErrorMsg;
                            window.location.reload(true);
                            sap.ui.core.BusyIndicator.hide();
                        } else {
                            sError = err.error;
                            sap.m.MessageBox.error(sError);
                            window.location.reload(true);
                            sap.ui.core.BusyIndicator.hide();
                        }
                        // window.location.href = '../logout';
                    }
                } else {
                    window.location.reload(true);
                    sap.ui.core.BusyIndicator.hide();
                }
            }
    
        });
    
    });

    Apart from above, you can simply create your pages and controllers and keep linking them in master page and manifest file.

    Changes in Detail Pages

    In Detail pages, you need to handle a few things:

    • Within On Init or Route Matched section, you need to unhide Master Section, in this use case it is hidden, as first page was Login, and we don’t want to show Master section. The code is as below:
      // By default it is set "HideMode" 
      this.getView().getParent().getParent().setMode("ShowHideMode");
      // This is to hide the Master Button over the master page invisible
      this.getView().getParent().getParent()._oShowMasterBtn.setVisible(false);

      In case, you directly go to Master Detail Section, just delete the mode from App.view.xml

    • You can hide and unhide Master tab/section on click of a button whose code is mentioned below
      We have written the code for button press “onExpandPress”:
      Button code: <Button icon=”sap-icon://full-screen” tooltip=”{i18n>Expand}” press=”onExpandPress”/>
      Controller Code:

      /**
               * onExpandPress is invoked from UI on press of button Expand. 
               * Input: current mode -- Full Screen or Pane Screen
               * Output: opposite mode -- Pane Screen or Full Screen
               */
      
              onExpandPress: function (oEvent) {
                  var navVisible = this.getView().getParent().getParent().getMode();
                  if (navVisible === "ShowHideMode") {
                      this.getView().getParent().getParent().setMode("HideMode");
                      oEvent.getSource().setIcon("sap-icon://exit-full-screen");
                  } else {
                      this.getView().getParent().getParent().setMode("ShowHideMode");
                      oEvent.getSource().setIcon("sap-icon://full-screen");
                  }
                  this.getView().getParent().getParent()._oShowMasterBtn.setVisible(false);
              },