Category: UI5

  • Image to Base64 Converter using SAP UI5

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

    When do we need to convert an Image to Base64

    You may want to convert an image to Base64 format for various reasons, some common use cases are:

    1. Storing images in databases: Instead of storing images as physical files, converting them to Base64 and storing the string in the database can simplify database management.
    2. Sending images in APIs: When sending images in APIs or other network protocols, it is often necessary to encode them as text-based data such as Base64, so they can be transmitted in a plain text format.
    3. Embedding images in HTML, CSS, or JavaScript: You can embed Base64 encoded images directly in your HTML, CSS, or JavaScript code, reducing the number of HTTP requests required to load a page.
    4. Reducing image file sizes: Base64 encoding increases the size of an image file, but it can be a useful optimization when multiple images are embedded in a single document, as it reduces the number of files that need to be loaded.

    It is worth noting that Base64 encoding increases the size of an image file by about 33%, so it’s not the most efficient way to store large images. However, for smaller images and icons, the overhead is usually not a problem.

    Steps to convert an Image to Base64 using JavaScript

    Here are the steps to convert an image to Base64 using JavaScript:

    1. Read the image file as a binary string using the FileReader API:

    const reader = new FileReader();
    
    reader.readAsDataURL(file);
    
    2. Once the file has been read, the load event will be triggered, and the result will be available in the reader.result property. This result will be a data URL that represents the image in Base64 format:
    reader.addEventListener("load", function() {
      const base64 = reader.result;
    });
    

    3. You can use the base64 variable in your JavaScript code to access the image data. For example, you can create an HTML img element and set its src attribute to the Base64 encoded image data:

    const image = new Image();
    image.src = base64;
    

    Here’s a complete example that reads an image file and displays it on a page:

    const input = document.querySelector("input[type='file']");
    const imageContainer = document.querySelector("#image-container");
    
    input.addEventListener("change", function(event) {
      const file = event.target.files[0];
      const reader = new FileReader();
    
      reader.readAsDataURL(file);
    
      reader.addEventListener("load", function() {
        const base64 = reader.result;
        const image = new Image();
        image.src = base64;
        imageContainer.appendChild(image);
      });
    });
    

     

    Steps to convert an Image to Base64 using SAP UI5

    In SAP UI5, you can use FileReader() function to convert the same. Codes are mentioned below:

    View.xml

    <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" xmlns:RichTextEditor="sap.ui.richtexteditor">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Image to Base64 Converter using UI5">
                        <content>
                            <VBox class="sapUiSmallMarginBegin">
                                <HBox>
                                    <UploadCollection id="idDP" noDataText="Upload a square image preferably 640X640"
                                        maximumFilenameLength="30" maximumFileSize="1" multiple="false"
                                        sameFilenameAllowed="false" instantUpload="false" change="onChangeDP" fileDeleted="onFileDeletedDP" fileType="png,jpg,jpeg"
                                        filenameLengthExceed="onFilenameLengthExceed" fileSizeExceed="on1MBFileSizeExceed" typeMissmatch="onTypeMissmatch"
                                        uploadComplete="onUploadDPComplete" beforeUploadStarts="onBeforeUploadStarts"/>
                                    <TextArea id="idBase64Area" value='Base 64 Value' editable="false" height="300px" width="500px"/>
                                </HBox>
                            </VBox>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onChangeDP: function (oEvent) {
                // Get File
                var that = this;
                var image = new Image();
                var file = oEvent.getParameter("files")[0];
                var reader = new FileReader();
                reader.readAsDataURL(file);
                reader.onload = function () {
                    var data = reader.result;
                    //Set the Base64 string return from FileReader as text area value.
                    that.byId("idBase64Area").setValue(data);
                    image.onload = function () {
                        //	Check if image is bad/invalid
                        if (this.width + this.height === 0) {
                            that.dpImage = "";
                            sap.m.MessageBox.error("Invalid Image!");
                        }
                    };
                };
                reader.onerror = function (error) {
                    //Error Handling
                };
            }
    
        });
    });

    Output

    Image to Base64 Converter using UI5

     

  • Text to HTML Converter Integration in SAP UI5

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

    Introduction

    A Text to HTML Converter is a tool or software program that converts plain text into HTML (HyperText Markup Language) format. HTML is a markup language used to create web pages and display content on the internet. The HTML format provides a way to structure text and add visual elements, such as headings, paragraphs, lists, images, and links.

    When you use a Text to HTML Converter, you can take plain text and turn it into an HTML document, which can then be displayed on the web. The converter adds the necessary HTML tags and syntax to format the text and create a web page. This can be useful for people who want to publish text content on the web but don’t have experience with HTML coding.

    When do we need to convert Text to HTML in UI5?

    In SAP UI5, you might need to convert text to HTML when you want to display dynamic content on a web page, and you need to format that content in a specific way. For example, you might want to display text with different fonts sizes, colors, or styles. You might also want to include links, images, or lists in your content.

    When you use UI5 to build web applications, you can use the HTML format to create rich and dynamic user interfaces. The conversion from plain text to HTML can be done programmatically, for example, in a controller or helper class, and then the HTML content can be added to a UI5 control, such as a sap.m.Text control, for display in the user interface.

    This allows you to dynamically create and display formatted content in your UI5 applications, and provides a flexible and powerful way to present data and information to your users.

    The major business use case for Text to HTML converters is for the creation of an Email template. A business guy will create a template for you, and you will have to convert it into HTML, so that the same can be sent via Email. An email always sends data in HTML format.

    Text to HTML Converter Integration in SAP UI5

    1. Using RichTextEditor

    You can use RichTextEditor in view (commented here) or in the controller. When you try to get its value using getValue() function, then it always return HTML format data.

    View.xml

    <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" xmlns:RichTextEditor="sap.ui.richtexteditor">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="Text to HTML Converter using UI5">
                        <content>
                            <VBox class="sapUiSmallMarginBegin">
                                <HBox>
                                    <!--<RichTextEditor:RichTextEditor id="RichTextEditor1" height="300px" width="500px"/>-->
                                    <Text id="text2" class="sapUiSmallMarginBeginEnd sapUiSmallMarginTop"/>
                                    <VBox id="editorContainer"></VBox>
                                    <VBox class="sapUiLargeMargin">
                                        <Button text="Convert" width="100px" press="onConvert"/>
                                        <Button id="uploadText" text="Copy" width="100px" enabled="false" press="onSave"/>
                                    </VBox>
                                    <TextArea id="RichTextEditor2" value='' editable="false" height="300px" width="500px"/>
                                </HBox>
                            </VBox>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    Controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
                var that = this;
                sap.ui.require(["sap/ui/richtexteditor/RichTextEditor"],
                    function (RTE) {
                        that.oRichTextEditor = new RTE("myRTE", {
                            editorType: sap.ui.richtexteditor.EditorType.TinyMCE,
                            width: "500px",
                            height: "300px",
                            showGroupFont: true,
                            tooltip: "Enter Text",
                            value: ""
                        });
    
                        that.getView().byId("editorContainer").addItem(that.oRichTextEditor);
                    });
            },
    
            onConvert: function () {
                var text = this.getView().byId("RichTextEditor2");
                var value = this.getView().byId("editorContainer").getItems()[0].getValue();
                if (value.length > 0) {
                    text.setValue(value);
                    this.getView().byId("uploadText").setEnabled(true);
                } else {
                    sap.m.MessageBox.information("Empty Input. Please type something");
                }
            }
        });
    });

    Output

    Text to HTML Converter using UI5

    2. Using JavaScript

    In SAP UI5, you can integrate a Text to HTML Converter in your web application by using JavaScript or any other programming language. Here’s an example of how you could implement a Text to HTML Converter in a UI5 application using JavaScript:

    1. Create a function that converts text to HTML format. This function can be called whenever you need to convert text to HTML.
      function convertTextToHTML(text) {
        // Use regular expressions or other string manipulation techniques to convert the text to HTML format
        var html = text.replace(/\n/g, "<br>");
        return html;
      }
      
    2. In your UI5 controller or helper class, call the convertTextToHTML function and pass the text that you want to convert.
      var html = convertTextToHTML("This is some sample text\nThis is a new line");
      
    3. Finally, set the HTML content to a UI5 control, such as a sap.m.Text control, and add it to the view.
      var textControl = new sap.m.Text({
        text: html
      });
      this.getView().addContent(textControl);
      

      This is just one way to implement a Text to HTML Converter in SAP UI5. The exact implementation will depend on the specific requirements of your application, such as the format of the input text and the desired output HTML format. However, this example should give you a general idea of how to integrate a Text to HTML Converter in your UI5 application.

  • Outlook or Email Client Integration in SAP UI5

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

    Introduction

    Outlook or Email Client Integration in SAP UI5 is a crucial aspect of modern-day business operations, as it streamlines the process of communication and data management within an organization. By integrating your email client with SAP UI5, you can efficiently manage emails, appointments, and contacts directly from your SAP system. This integration provides a seamless experience for users, improving productivity and reducing the time spent on manual tasks. With the help of SAP UI5’s intuitive interface and advanced features, you can easily manage your email and other communication needs, optimizing your work processes and increasing your overall efficiency.

    When do we need to integrate Outlook or Email Client with UI5?

    You may need to integrate Outlook or an Email Client with SAP UI5 in the following scenarios:

    1. Centralized Communication Management: Integrating your email client with SAP UI5 allows you to manage all your communication in a single platform, reducing the time spent on switching between different systems.
    2. Improved Productivity: By integrating your email client with SAP UI5, you can automate repetitive tasks such as sending emails, scheduling appointments, and updating contacts. This saves time and improves overall productivity.
    3. Better Collaboration: Integrating your email client with SAP UI5 makes it easier for team members to communicate and collaborate on projects. You can easily share information and track email conversations directly from the SAP system.
    4. Enhanced Data Security: By keeping all your communication within a secure platform like SAP UI5, you can ensure that sensitive information is protected and only accessible by authorized users.
    5. Better Customer Experience: By integrating your email client with SAP UI5, you can provide a seamless and efficient customer experience. You can respond to customer inquiries, send updates, and manage customer information directly from your SAP system.

    How to open up Outlook or Email Client from UI5 with preformatted text?

    We can open up Outlook or another email client in UI5 in two different ways:

    1. Using mailto URL scheme

    To open Outlook or an Email Client from SAP UI5 with preformatted text, you can use a combination of JavaScript and the mailto URL scheme. Here’s an example of how you can achieve this:

    var emailSubject = "SAP UI5 Email Integration";
    var emailBody = "Hello,\n\nThis is an email generated from SAP UI5.\n\nBest regards,\nSAP UI5 Team";
    var emailTo = "recipient@example.com";
    
    var mailLink = "mailto:" + emailTo + "?subject=" + encodeURIComponent(emailSubject) + "&body=" + encodeURIComponent(emailBody);
    
    window.location.href = mailLink;
    

    In this example, the email subject, body, and recipient’s email address are defined as variables. The mailto URL scheme is then used to create a mailto link, which opens up the email client with the preformatted text. The encodeURIComponent function is used to properly encode the subject and body text for use in a URL.

    When this code is executed, it opens the default email client with the specified subject, body, and recipient. Note that the behavior of this code may vary based on the email client being used and the settings on the user’s device.

    2. Using sap.m.URLHelper.triggerEmail

    The sap.m.URLHelper.triggerEmail method is a part of the SAP UI5 library and can be used to open the default email client with preformatted text. Here’s an example of how you can use this method:

    In this method we will try to create something where you can even select fields from UI and pass them to email like shown below:

    sap.m.URLHelper.triggerEmail("recipient@example.com", "SAP UI5 Email Integration", "Hello,\n\nThis is an email generated from SAP UI5.\n\nBest regards,\nSAP UI5 Team");
    

    In this example, the triggerEmail method takes three parameters: the recipient’s email address, the email subject, and the email body. When this code is executed, it opens the default email client with the specified subject, body, and recipient.

    This method provides a simpler and more convenient way to open the email client compared to manually constructing a mailto link. Additionally, it ensures that the email text is properly encoded for use in a URL.

    View.xml

    <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="App to show Email Client Integration in SAP UI5">
                        <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"/>
                                    <Button id="onHelpPress" text="Help" press="onHelpPress"/>
                                </contentLeft>
                            </Bar>
                        </footer>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    Controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/MessageBox"
    ], function (Controller, MessageBox) {
        "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();
            },
    
            onHelpPress: function () {
                // Get data from selection on screen
                if (window.getSelection().baseNode === null) {
                    MessageBox.error(
                        "Please highlight the field and value for which you want to report issue!"
                    );
                } else {
                    var selectedData = window.getSelection().focusNode.nodeValue;
                    var getSelectedField = window.getSelection().anchorNode.nodeValue;
                    // Check if there was any selection
                    if (selectedData === null || getSelectedField === null) {
                        MessageBox.error(
                            "Please highlight the field and value for which you want to report issue!"
                        );
                    } else {
                        // Trigger email with custom email data
                        sap.m.URLHelper.triggerEmail("contact@rudelabs.in", "RUDE LABS: Data Issue for Customer " + selectedData, "Hello " + "Team" +
                            ", \n\n" +
                            "Kindly look into the Address with the following details: \n" +
                            "Customer name: " + selectedData + "\n" +
                            "Current Address: " + getSelectedField + "\n" +
                            "Reporter User ID: " + sap.ushell.Container.getService("UserInfo").getId() + "\n\n\n\n" +
                            "Thanks & Regards," + "\n" +
                            sap.ushell.Container.getService("UserInfo").getUser().getFullName()
                        );
                    }
                }
            }
    
        });
    });

     

    Output

    Selection of fields on UI5 screen

     

    Email triggerEmail

  • 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);
              },