Category: UI5 Programs

  • Implementing Cookie Settings in SAP UI5

    Introduction

    With the constant evolution of the web and the various platforms that power it, ensuring a seamless user experience is crucial. In SAP UI5, a key component that aids in enhancing this experience is the use of cookies. Through this article, we’ll delve into the realm of cookies in SAP UI5, why they’re essential, and how to set them up for optimal use.

    What is a Cookie and why is it required in SAP UI5?

    A cookie is a small piece of data sent from a website and stored in a user’s web browser. They remember stateful information for the stateless HTTP protocol. In SAP UI5, cookies play an essential role in retaining user preferences, maintaining sessions, or even tracking user interactions, ensuring users don’t have to re-enter preferences every time they revisit an application.

    Client-side Cookies vs. server-side Cookies

    In the realm of web development, cookies can generally be categorized into two types:

    • Client-side Cookies: These are stored on the user’s browser and can be read using JavaScript when the user revisits the site. They are primarily used for local preferences, theme settings, or even short-term tracking.
    • Server-side Cookies: These are processed on the web server and can be read on subsequent HTTP requests made to the server for the same domain. They are mainly utilized for sessions, user authentication, and more persistent tracking.

    In SAP UI5, depending on your requirements, you might lean towards one type of cookie over the other, or even use a combination of both.

    Set cookie and get a cookie with JavaScript in SAP UI5

    Using JavaScript in SAP UI5 to set and retrieve cookies is straightforward.

    Setting a Cookie:

    function setCookie(name, value, days) {
        let expires = "";
        if (days) {
            const date = new Date();
            date.setTime(date.getTime() + (days*24*60*60*1000));
            expires = "; expires=" + date.toUTCString();
        }
        document.cookie = name + "=" + (value || "") + expires + "; path=/";
    }
    

    Usage:

    setCookie("userPreference", "darkTheme", 7);
    

    Getting a Cookie:

    function getCookie(name) {
        const nameEQ = name + "=";
        const cookiesArray = document.cookie.split(';');
        for(let i=0; i < cookiesArray.length; i++) {
            let cookie = cookiesArray[i];
            while (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);
            if (cookie.indexOf(nameEQ) == 0) return cookie.substring(nameEQ.length, cookie.length);
        }
        return null;
    }
    

    Usage:

    const userPreference = getCookie("userPreference");
    

     

    Adding Cookies to a Request

    When making AJAX calls in SAP UI5, you might need to send cookies along with your request. Here’s a simple way to do it:

    Using the jQuery ajax method:

    $.ajax({
        url: "https://yourapiendpoint.com/data",
        type: "GET",
        xhrFields: {
            withCredentials: true
        },
        success: function(data) {
            // Handle data here
        }
    });
    

    The withCredentials: true ensures that cookies are sent with the request. Remember that the server also needs to accept credentials from the origin by setting the appropriate CORS headers.

  • How to create introduction guides in SAP UI5

    Introduction

    In modern web applications, ensuring that users understand and navigate through the interface efficiently is paramount. This becomes especially vital in comprehensive platforms like SAP UI5, where complex functionalities and data-driven interfaces are the norms. “How to create introduction guides in SAP UI5” serves as a comprehensive guide to set up intuitive step-by-step onboarding instructions for your SAP UI5 application. From header bars, filters, tables, to footer buttons, this guide elucidates how to create a guided tour, ensuring that users have a clear understanding of each interface element. Dive in to provide your users with a smooth introduction to your UI5 application’s functionalities.

    How to create introduction guides in SAP UI5

    How to create introduction guides in SAP UI5

    To implement the introduction guide along with the described page, you can leverage the sap.m library of SAP UI5 and the sap.ui.core.delegate.ItemNavigation class for the guided introduction. Let’s go step-by-step:

    1. Initial Setup

    Include the required libraries in your XML view:

    xmlns:m="sap.m"
    xmlns:core="sap.ui.core"
    

    2. Setup View with hardcoded data

    <mvc:View controllerName="IntroductionGuides.IntroductionGuides.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
        xmlns="sap.m" xmlns:core="sap.ui.core">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page title="My Page">
                        <customHeader>
                            <Bar>
                                <contentRight>
                                    <Button text="Profile" id="profileBtn"/>
                                    <Button text="Logout" id="logoutBtn"/>
                                </contentRight>
                            </Bar>
                        </customHeader>
                        <content>
                            <VBox>
                                <!-- Filter Section -->
                                <HBox>
                                    <Input placeholder="Search..." id="searchFilter"/>
                                    <ComboBox>
                                        <core:Item key="1" text="Item 1"/>
                                        <core:Item key="2" text="Item 2"/>
                                    </ComboBox>
                                </HBox>
                                <!-- Table Section -->
                                <Table id="dataTable">
                                    <columns>
                                        <Column width="12em">
                                            <Text text="Product"/>
                                        </Column>
                                        <Column minScreenWidth="Tablet" demandPopin="true">
                                            <Text text="Supplier"/>
                                        </Column>
                                    </columns>
                                    <items>
                                        <ColumnListItem>
                                            <cells>
                                                <Text text="Product 1"/>
                                                <Text text="SupplierName 1"/>
                                            </cells>
                                        </ColumnListItem>
                                    </items>
                                </Table>
                            </VBox>
                        </content>
                        <footer>
                            <Bar id="footerBar">
                                <contentRight>
                                    <Button text="Button 1"/>
                                    <Button text="Button 2"/>
                                </contentRight>
                            </Bar>
                        </footer>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    3. Build the Page Layout

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/Popover"
    ], function (Controller, Popover) {
        "use strict";
    
        return Controller.extend("IntroductionGuides.IntroductionGuides.controller.View1", {
    
            onAfterRendering: function () {
                this.getView().setModel(new sap.ui.model.json.JSONModel({
                    hardcodedData: [ /* your data here */ ],
                    hardcodedFilters: [ /* your filter data here */ ]
                }));
    
                // Start the introduction guide once the UI is rendered
                this.startIntroduction();
            },
    
            startIntroduction: function () {
                var aSteps = [{
                    id: "profileBtn",
                    text: "This is the profile button."
                }, {
                    id: "logoutBtn",
                    text: "Click here to log out."
                }, {
                    id: "searchFilter",
                    text: "Search using this filter."
                }, {
                    id: "comboFilter",
                    text: "Choose filters from this dropdown."
                }, {
                    id: "dataTable",
                    text: "This is your main data table."
                }, {
                    id: "footerBar",
                    text: "Footer contains various operations."
                }];
    
                var iCurrentStep = 0;
    
                var fnShowStep = function () {
                    if (iCurrentStep >= aSteps.length) {
                        // Completed the introduction
                        return;
                    }
    
                    var oControl = this.getView().byId(aSteps[iCurrentStep].id);
                    if (!oControl) {
                        iCurrentStep++;
                        fnShowStep.call(this);
                        return;
                    }
    
                    var oPopover = new Popover({
                        title: "Step " + (iCurrentStep + 1),
                        content: new sap.m.Text({
                            text: aSteps[iCurrentStep].text
                        }),
                        contentWidth: "350px", // set the desired width here
                        placement: sap.m.PlacementType.Bottom, // initially set to show below the control
                        footer: new sap.m.Toolbar({
                            content: [
                                new sap.m.ToolbarSpacer(),
                                new sap.m.Button({
                                    text: "Next",
                                    press: function () {
                                        oPopover.close();
                                        iCurrentStep++;
                                        fnShowStep.call(this);
                                    }.bind(this)
                                })
                            ]
                        })
                    });
    
                    var oControlPosition = oControl.getDomRef().getBoundingClientRect();
                    if (oControlPosition.top > window.innerHeight / 2) {
                        oPopover.setPlacement(sap.m.PlacementType.Top); // if control is in the bottom half of the screen, show popover above it
                    }
    
                    oPopover.openBy(oControl);
                };
    
                fnShowStep.call(this);
            }
    
        });
    });

    The startIntroduction method will contain the logic for showcasing different sections. This logic can use modals, popovers, or tooltips to display guidance text. For brevity, I’ve not implemented the detailed logic in the example, but you can use libraries like Intro.js or write custom logic to guide users through the different sections.

    The general idea is to highlight and provide information for each section, making the UI interactive and user-friendly for new users.

  • How to Display Disclaimer Page for GDPR in SAP UI5?

    Introduction

    Learn the straightforward approach to displaying a GDPR-compliant disclaimer page in SAP UI5. In this guide, we walk you through the steps to create a popup that appears as your application starts, ensuring users read and acknowledge the disclaimer before proceeding. This method, leveraging the sap.m.Dialog and sap.m.VBox controls, is crucial for applications needing to meet GDPR requirements. Follow along to integrate this solution into your SAP UI5 application.

    How to Display Disclaimer Page for GDPR in SAP UI5

    How to Display Disclaimer Page for GDPR in SAP UI5?

    To achieve this in SAP UI5, you can use a Dialog control with a CheckBox inside. Here’s a step-by-step guide to create this functionality:

    1. Add necessary libraries: Ensure you’ve added the following libraries to your SAP UI5 project’s index.html or as per your application structure:

    <script src="resources/sap/m/library.js" id="sap-ui-bootstrap"></script>
    <script src="resources/sap/ui/layout/library.js"></script>
    

     

    2. Create the Disclaimer Dialog: You can add this in your Component.js or App.controller.js‘s onInit function or any initial function that loads as soon as the app starts.

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/Dialog",
        "sap/m/Text",
        "sap/m/CheckBox",
        "sap/m/Button"
    ], function(Controller, Dialog, Text, CheckBox, Button) {
        "use strict";
    
        return Controller.extend("your.controller.path", {
            onInit: function() {
                this._showDisclaimer();
            },
    
            _showDisclaimer: function() {
        var oVBox = new sap.m.VBox({
            items: [
                new sap.m.Text({ 
                    text: 'Your GDPR compliance related content here. By continuing to use this application, you accept the data terms and conditions.' 
                }),
                new sap.m.CheckBox({ 
                    text: 'I have read and understood the disclaimer', 
                    selected: false 
                })
            ]
        });
    
        var oDisclaimerDialog = new sap.m.Dialog({
            title: 'Disclaimer',
            content: [oVBox],
            beginButton: new sap.m.Button({
                text: 'Continue',
                enabled: false,  // Disabled initially
                press: function() {
                    oDisclaimerDialog.close();
                    
                    // Logic to save acceptance in the database would be here.
                    
                    // Display the success message
                    sap.m.MessageToast.show("Your acceptance is saved in the database, you will not be asked again!");
                }
            }),
            afterClose: function() {
                oDisclaimerDialog.destroy();
            }
        });
    
        oDisclaimerDialog.open();
    
        // Enabling the continue button only when the checkbox is selected
        oVBox.getItems()[1].attachSelect(function(oEvent) {
            var bSelected = oEvent.getParameter("selected");
            oDisclaimerDialog.getBeginButton().setEnabled(bSelected);
        });
    }
    
        });
    });
    

    The above code snippet places the Text and CheckBox inside a VBox. This VBox is then set as the content of the Dialog. This arrangement ensures a neat vertical alignment of the disclaimer content and the checkbox.

    In the press event of the “Continue” button, right after closing the dialog, the sap.m.MessageToast is used to display a success message. Note that you will need to incorporate the logic to save this acceptance to the database where I have added the comment.

  • Print Full Screen in SAP UI5

    Introduction

    Learn how to print a full screen in SAP UI5 using this straightforward guide. Using HTML and JavaScript, we’ll walk you through the steps to integrate efficient printing capabilities in your SAP UI5 application. Whether it’s an entire page or specific sections, this tutorial ensures you capture the details you need. Enhance your SAP UI5 user experience by adding this practical feature. Thus, you will learn How to print UI5 page.

    Print in SAP UI5 using Windows Function

    To perform a print in SAP UI5 using HTML and JavaScript, you can utilize the `window.print()` method. This method prompts the user to print the current page. You can just use CTRL + P in your keyboard to trigger print in Windows laptops.

    Here’s a simple way to do it:

    1. Create a Button in your XML View:

    <Button text="Print" press="onPrint"/>
    

    2. Define the onPrint function in your Controller:

    onPrint: function() {
        window.print();
    }
    

    When the button is pressed, the `onPrint` function will be executed, and the user will be prompted to print the current page.

    Print in SAP UI5 after converting to Image

    HTML Code:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>

    View Code:

    <Button text="Print after converting to Image" press="onPrinCapturet"/>

    Controller Code:

    onPrinCapturet: function () {
                var oPage = this.getView().byId("page"); // Assuming "page" is the id of your main Page or container in the XML view
    
                if (oPage && oPage.getDomRef()) {
                    var oDomElement = oPage.getDomRef();
    
                    html2canvas(oDomElement).then(canvas => {
                        var oImgData = canvas.toDataURL("image/png");
    
                        // Open a new window or iframe and load the image data to print
                        var oPrintWindow = window.open('', '_blank');
                        oPrintWindow.document.write('<img src="' + oImgData + '" onload="window.print();"/>');
                    });
                }
            },

    Print specific content in SAP UI5

    However, if you want to print specific content (not the entire page), you can utilize a hidden `iframe`:

    1. Create a Hidden iFrame in your HTML:

    <iframe id="printFrame" style="display:none;"></iframe>
    

    2. Add the Print Button in the View:

    Add id as “idFrame” to the view.

    <Button text="PrintFrame" press="onPrint"/>
    

    3. JavaScript to load content and print:

    onPrintFrame: function () {
        var oFrame = document.getElementById("printFrame");
        var oContentWindow = oFrame.contentWindow;
        var oDoc = oContentWindow.document;
        // var oViewContent = this.getView().getContent()[0]; // get content of the whole view
        var oViewContent = this.getView().byId("idFrame");  // get content of the vbox view
        var sHtml = oViewContent.getDomRef().outerHTML;
        oDoc.open();
        oDoc.write("<html><head><title>Print Content</title></head><body>");
        // oDoc.write("<h1>This is the content to print</h1>"); // Replace this with the content you want to print
        oDoc.write(sHtml);  // passing the content of the UI5 view
        oDoc.write("</body></html>");
        oDoc.close();
        oContentWindow.print();
    }

    In the example above, the content to print is loaded into the hidden iFrame and then printed. This way, only the specific content (and not the entire UI5 application) gets printed.

    Please note: Printing from a web application can vary based on the browser, so always test your printing function on different browsers to ensure compatibility.

     

    Full Code

    HTML

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>My Project Ideas</title>
            <link rel="icon" type="image/x-icon" href="https://myprojectideas.com/wp-content/uploads/2021/08/cropped-Screenshot-2021-07-26-at-1.39.04-PM.png"/>
            <script id="sap-ui-bootstrap"
                src="resources/sap-ui-core.js"
                data-sap-ui-theme="sap_fiori_3"
                data-sap-ui-resourceroots='{"PrintPage.PrintPage": "./"}'
                data-sap-ui-compatVersion="edge"
                data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
                data-sap-ui-async="true"
                data-sap-ui-frameOptions="trusted">
            </script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>
        </head>
        <body class="sapUiBody">
            <iframe id="printFrame" style="display:none;"></iframe>
            <div data-sap-ui-component data-name="PrintPage.PrintPage" data-id="container" data-settings='{"id" : "PrintPage"}'></div>
        </body>
    </html>
    

     

    View

    <mvc:View controllerName="PrintPage.PrintPage.controller.View1" xmlns:core="sap.ui.core" xmlns:layout="sap.ui.layout"
        xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page">
                        <content>
                            <VBox id="idFrame" justifyContent="Center" alignItems="Center" class="sapUiMediumMargin">
                                <!-- Invoice Heading -->
                                <Title text="Invoice" level="H1" class="sapUiSmallMarginBottom"/>
                                <!-- Invoice Date -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Invoice Date:" class="sapUiSmallMarginEnd"/>
                                    <Text text="20.09.2023"/>
                                </HBox>
                                <!-- Company Name -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Company Name:" class="sapUiSmallMarginEnd"/>
                                    <Text text="RUDE LABS Pvt Ltd"/>
                                </HBox>
                                <!-- Address -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Address:" class="sapUiSmallMarginEnd"/>
                                    <Text text="123, Web Street, Noida, 45678"/>
                                </HBox>
                                <!-- Service Details -->
                                <Title text="Service Details" level="H2" class="sapUiSmallMarginBottom"/>
                                <Table class="sapUiMediumMarginBottom">
                                    <columns>
                                        <Column><Text text="Service Name"/></Column>
                                        <Column><Text text="Description"/></Column>
                                        <Column><Text text="Amount"/></Column>
                                    </columns>
                                    <items>
                                        <ColumnListItem>
                                            <cells>
                                                <Text text="Website Development "/>
                                                <Text text="First Installment"/>
                                                <Text text="1000 USD"/>
                                            </cells>
                                        </ColumnListItem>
                                    </items>
                                </Table>
                                <!-- Total Amount -->
                                <HBox justifyContent="End" class="sapUiSmallMarginBottom">
                                    <Label text="Total Amount:" class="sapUiSmallMarginEnd"/>
                                    <Text text="1000 USD"/>
                                </HBox>
                                <!-- Footer Note -->
                                <Text text="Thank you for doing business with us!" class="sapUiSmallMarginTop"/>
                            </VBox>
                            <Button text="Default Print" press="onPressPrint"/>
                            <Button text="Print after converting to Image" press="onPrinCapturet"/>
                            <Button text="PrintFrame" press="onPrintFrame"/>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("PrintPage.PrintPage.controller.View1", {
            onInit: function () {
    
            },
    
            onPrinCapturet: function () {
                var oPage = this.getView().byId("page"); // Assuming "page" is the id of your main Page or container in the XML view
    
                if (oPage && oPage.getDomRef()) {
                    var oDomElement = oPage.getDomRef();
    
                    html2canvas(oDomElement).then(canvas => {
                        var oImgData = canvas.toDataURL("image/png");
    
                        // Open a new window or iframe and load the image data to print
                        var oPrintWindow = window.open('', '_blank');
                        oPrintWindow.document.write('<img src="' + oImgData + '" onload="window.print();"/>');
                    });
                }
            },
    
            onPressPrint: function (oEvent) {
                window.print();
            },
    
            onPrintFrame: function () {
                var oFrame = document.getElementById("printFrame");
                var oContentWindow = oFrame.contentWindow;
                var oDoc = oContentWindow.document;
                // var oViewContent = this.getView().getContent()[0]; // get content of the whole view
                var oViewContent = this.getView().byId("idFrame");  // get content of the vbox view
                // var sHtml = oViewContent.getDomRef().outerHTML;
                oDoc.open();
                oDoc.write("<html><head><title>Print Content</title></head><body>");
                // oDoc.write("<h1>This is the content to print</h1>"); // Replace this with the content you want to print
                oDoc.write(sHtml);  // passing the content of the UI5 view
                oDoc.write("</body></html>");
                oDoc.close();
                oContentWindow.print();
            }
    
        });
    });

     

  • Planning Calendar in SAP UI5

    Introduction

    The SAP UI5 Planning Calendar is a powerful, feature-rich tool that aids in visualizing, scheduling, and managing appointments or tasks efficiently. Designed to be user-friendly and intuitive, the Planning Calendar offers an overview of appointments or tasks over various views, including hours, days, 1 week, 1 month, or even a custom-defined timeline.

    Key features of the Planning Calendar include the ability to display appointments over different intervals, support for both single and multiple row layouts, various appointment types, and built-in controls for navigating between different intervals. It is designed with flexibility in mind and can be adapted to handle a variety of use cases. Appointments can be selected, resized, or moved according to your needs, and the overall look and feel of the calendar can be customized as well.

    In addition to these, the Planning Calendar also offers built-in support for handling different time zones, special dates like holidays or non-working days, and it even supports screen readers for accessibility.

    Whether you’re developing an employee scheduling app, a project management tool, a room booking system, or any other application where time-bound events need to be visualized and managed, the SAP UI5 Planning Calendar can be a great asset. It simplifies complex scheduling tasks, improves productivity, and delivers a superior user experience, aligning perfectly with SAP’s philosophy of helping the world run better.

    In the next sections, we will delve deeper into how to use and customize the SAP UI5 Planning Calendar, enriching it with our application-specific data and functionality.

    Why we need Planning Calendar in SAP UI5

    In any organization or business application, managing time and events efficiently is crucial to achieving goals and maintaining order. This is where the SAP UI5 Planning Calendar comes into play. Here are a few reasons why it’s needed:

    1. Ease of use: With its user-friendly interface, the SAP UI5 Planning Calendar simplifies the task of creating, viewing, and managing appointments. It provides an intuitive visualization of events, which allows users to grasp their schedules quickly.

    2. Flexibility: The SAP UI5 Planning Calendar is flexible and can be adapted to a variety of use cases. Whether it’s managing employee schedules, tracking project timelines, or scheduling room bookings, the Planning Calendar can be customized to fit your needs.

    3. Rich Feature Set: The SAP UI5 Planning Calendar comes packed with features such as support for different intervals (hours, days, 1 week, 1 month), different appointment types, and multiple row layouts. This allows the calendar to cater to a wide range of scheduling requirements.

    4. Efficiency: It improves efficiency by reducing the time and effort needed to schedule and reschedule appointments or tasks. Users can easily select, resize, or move appointments according to their needs.

    5. Consistency: By using the Planning Calendar in SAP UI5, you maintain consistency with other SAP applications. This allows for a seamless user experience across all your business applications.

    6. Accessibility: The Planning Calendar in SAP UI5 is designed with accessibility in mind, with built-in support for screen readers. This ensures that the tool can be used by people with diverse abilities, adhering to inclusivity standards.

    7. Customization: The look and feel of the calendar can be tailored according to your needs, enabling you to maintain the branding and aesthetics of your application.

    8. Integration: It seamlessly integrates with other SAP UI5 controls and services, making it a robust choice for applications built on the SAP platform.

    In summary, the SAP UI5 Planning Calendar provides a robust, user-friendly, and efficient way to handle scheduling tasks in your applications.

    How to develop Planning Calendar in SAP UI5

    View

    <mvc:View controllerName="PlanningCalendar.PlanningCalendar.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
        xmlns:unified="sap.ui.unified">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="My Project Ideas: Planning Calendar in SAP UI5">
                        <content>
                            <Button text="Block for Next Meeting" press="onPressBlock"/>
                            <PlanningCalendar id="planningCalendar" startDate="{path: '/startDate'}" rows="{path: '/rows'}" appointmentsVisualization="Filled"
                                appointmentSelect="handleAppointmentSelect" showEmptyIntervalHeaders="false" showWeekNumbers="true">
                                <rows>
                                    <PlanningCalendarRow startDate="{startDate}" appointments="{appointments}">
                                        <appointments>
                                            <unified:CalendarAppointment resizable="true" startDate="{startDate}" endDate="{endDate}" title="{title}" text="{text}" type="{type}"
                                                resize="handleAppointmentResize"/>
                                        </appointments>
                                    </PlanningCalendarRow>
                                </rows>
                            </PlanningCalendar>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/ui/model/json/JSONModel",
        'sap/m/MessageBox',
        'sap/ui/core/date/UI5Date'
    ], function (Controller, JSONModel, MessageBox, UI5Date) {
        "use strict";
    
        return Controller.extend("PlanningCalendar.PlanningCalendar.controller.Main", {
            onInit: function () {
                var currentDate = new Date();
                var oData = {
                    startDate: new Date(),
                    rows: [{
                        startDate: new Date(),
                        appointments: [{
                            startDate: new Date(),
                            endDate: new Date(currentDate.getTime() + (3 * 60 * 60 * 1000)),
                            title: "Meeting with SAP",
                            text: "Discuss project status",
                            type: "Type01",
                            pic: "sap-icon://sap-ui5",
                        }]
                    }]
                };
    
                var oModel = new JSONModel(oData);
                this.getView().setModel(oModel);
            },
    
            handleAppointmentSelect: function (oEvent) {
                var oAppointment = oEvent.getParameter("appointment"),
                    sSelected;
                if (oAppointment) {
                    sSelected = oAppointment.getSelected() ? "selected" : "deselected";
                    MessageBox.show("'" + oAppointment.getTitle() + "' " + sSelected);
                } else {
                    var aAppointments = oEvent.getParameter("appointments");
                    var sValue = aAppointments.length + " Appointments selected";
                    MessageBox.show(sValue);
                }
            },
    
            onPressBlock: function (oEvent) {
                var currentDate = new Date();
                var oData = {
                    startDate: new Date(),
                    rows: [{
                        startDate: new Date(),
                        appointments: [{
                            startDate: new Date(),
                            endDate: new Date(currentDate.getTime() + (3 * 60 * 60 * 1000)),
                            title: "Meeting with SAP",
                            text: "Discuss project status",
                            type: "Type01",
                            pic: "sap-icon://sap-ui5",
                        }, {
                            startDate: new Date(currentDate.getTime() + (3 * 60 * 60 * 1000)),
                            endDate: new Date(currentDate.getTime() + (6 * 60 * 60 * 1000)),
                            title: "Next Meeting with SAP",
                            text: "Discuss Next Meeting",
                            type: "Type02",
                            pic: "sap-icon://sap-ui5",
                            tentative: false
                        }]
                    }]
                };
    
                var oModel = new JSONModel(oData);
                this.getView().setModel(oModel);
            }
        });
    });

     

    Output

    Planning Calendar in SAP UI5

  • VizFrame Chart in UI5 using local JSON or OData

    Introduction

    Introduction to VizFrame Chart in SAP UI5 using Local JSON or OData:

    VizFrame is a powerful data visualization control in SAP UI5 that empowers developers to create stunning charts and graphs for displaying data in a user-friendly and interactive manner. With VizFrame, you can visualize data from various sources, including local JSON and OData services. This introduction will explore how VizFrame can be leveraged to create dynamic and visually appealing charts using data from local JSON or OData services.

    1. Local JSON Data Source:
    Local JSON serves as an ideal data source for small to medium-sized datasets that are readily available within the application without the need for server-side communication. By utilizing the JSONModel in SAP UI5, developers can easily bind the local JSON data to the VizFrame control, allowing seamless data visualization directly within the application.

    2. OData Service Data Source:
    For larger datasets or real-time data, SAP UI5 offers integration with OData services. OData provides a standardized way to interact with remote data sources, enabling the VizFrame chart to visualize live data fetched from an external service. Leveraging the ODataModel, developers can efficiently connect the VizFrame chart to the OData service and automatically update the visualization as the data changes in the backend.

    Key Features of VizFrame Chart:
    – **Rich Chart Types:** VizFrame offers a wide range of chart types, including column charts, line charts, pie charts, bar charts, and more. You can select the most suitable chart type to present your data effectively.

    – **Interactive and Responsive:** VizFrame charts come with interactive features such as zooming, panning, and tooltips, providing users with a dynamic and engaging experience. The charts are responsive and adapt gracefully to various screen sizes and devices.

    – **Data Binding and Aggregation:** Whether using local JSON or OData services, VizFrame seamlessly binds data to the chart, allowing you to leverage data aggregation to summarize and group information for a clearer presentation.

    – **Customization and Theming:** Developers can easily customize the appearance of VizFrame charts by adjusting colors, labels, axis properties, and more. SAP UI5’s theming capabilities enable charts to harmonize with the overall application design.

    – **Integration with Other UI5 Controls:** VizFrame can be seamlessly integrated with other UI5 controls to build comprehensive and feature-rich analytical dashboards and applications.

    In conclusion, VizFrame in SAP UI5 is a versatile and user-friendly charting solution that enables developers to create visually compelling data visualizations using local JSON or OData services. By leveraging the power of VizFrame, developers can transform raw data into meaningful insights, empowering users to make informed decisions and gain valuable insights from their data.

    Important Terms to Understand

    In SAP UI5, the concept of Model, FlattenedDataset, and FeedItem is related to data visualization using VizFrame controls. VizFrame is a versatile UI5 control that allows you to create various types of charts and graphs for data representation.

    1. Model:
    A Model in SAP UI5 is an abstraction of data that allows you to access and manipulate data in a consistent way. It is a data binding concept that separates the control logic from the data. The Model provides a standard API to interact with the data, irrespective of the data source. There are various types of models, such as JSONModel, ODataModel, etc., which can be used based on the data source and requirements.

    2. FlattenedDataset:
    The FlattenedDataset is a specialized dataset used by VizFrame controls to represent data in a flattened format suitable for visualization. It takes tabular data and converts it into a format that can be easily understood by charts and graphs. The FlattenedDataset provides configuration options for defining dimensions (e.g., categories, groups) and measures (e.g., values, quantities) of the chart.

    3. FeedItem:
    The FeedItem is used in conjunction with the FlattenedDataset to define the mapping between the dimensions and measures of the FlattenedDataset and the corresponding axes of the chart. It defines which dimensions should be represented on which axis and which measures should be used for different aspects of the chart (e.g., axis values, colors, sizes).

    4. addFeed:
    In the context of VizFrame, addFeed is a method used to associate FeedItems with the FlattenedDataset. By adding FeedItems to the FlattenedDataset, you define how the data should be visualized in the chart. For example, you can specify that a particular dimension should be shown on the X-axis, or a certain measure should be used to determine the color of the chart elements.

    In summary, when using VizFrame for data visualization in SAP UI5, you create a FlattenedDataset to convert your tabular data into a suitable format for charting. You then use FeedItems to map dimensions and measures from the FlattenedDataset to specific aspects of the chart. Finally, you add these FeedItems to the FlattenedDataset using the addFeed method, allowing you to visualize the data in a meaningful and informative way.

    VizFrame Chart in UI5 using local JSON or OData

    View

    <mvc:View controllerName="vizChartJSON.vizChartJSON.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
        xmlns:viz="sap.viz.ui5.controls" xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="My Project Ideas: VizFrame Chart in UI5 using local JSON or OData">
                        <content>
                            <RadioButtonGroup id='datasetRadioGroup'>
                                <buttons>
                                    <RadioButton class='settingsRadio' text="Line" select="onDatasetSelectedLine"/>
                                    <RadioButton class='settingsRadio' text="Column" select="onDatasetSelecteColumn"/>
                                    <RadioButton class='settingsRadio' text="Bullet" select="onDatasetSelecteBullet"/>
                                    <RadioButton class='settingsRadio' text="Area" select="onDatasetSelecteArea"/>
                                </buttons>
                            </RadioButtonGroup>
                            <viz:VizFrame id="chartContainer" vizType="line" width="600px" height="400px"/>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/viz/ui5/data/FlattenedDataset",
        "sap/viz/ui5/controls/common/feeds/FeedItem"
    ], function (Controller, FlattenedDataset, FeedItem) {
        "use strict";
    
        return Controller.extend("vizChartJSON.vizChartJSON.controller.Main", {
            onInit: function () {
                var data = [{
                    "Category": "Category 1",
                    "Revenue": 100
                }, {
                    "Category": "Category 2",
                    "Revenue": 200
                }, {
                    "Category": "Category 3",
                    "Revenue": 300
                }, {
                    "Category": "Category 4",
                    "Revenue": 400
                }, {
                    "Category": "Category 5",
                    "Revenue": 500
                }];
                // Load local JSON data
                var oDataModel = new sap.ui.model.json.JSONModel(data);
                // Use this line in case you are loading from external OData url
                // oDataModel.loadData(data);
    
                // Get the VizFrame control
                var oChartContainer = this.getView().byId("chartContainer");
    
                // Set the data model to the VizFrame
                oChartContainer.setModel(oDataModel);
    
                // Create a FlattenedDataset
                var oDataset = new FlattenedDataset({
                    dimensions: [{
                        name: "Category",
                        value: "{Category}"
                    }],
                    measures: [{
                        name: "Revenue",
                        value: "{Revenue}"
                    }],
                    data: {
                        path: "/"
                    }
                });
    
                // Add the dataset to the VizFrame
                oChartContainer.setDataset(oDataset);
    
                // Create a FeedItem for Category dimension
                var oCategoryFeed = new FeedItem({
                    uid: "categoryAxis",
                    type: "Dimension",
                    values: ["Category"]
                });
    
                // Create a FeedItem for Revenue measure
                var oRevenueFeed = new FeedItem({
                    uid: "valueAxis",
                    type: "Measure",
                    values: ["Revenue"]
                });
    
                // Add the FeedItems to the VizFrame
                oChartContainer.addFeed(oCategoryFeed);
                oChartContainer.addFeed(oRevenueFeed);
            },
            
            onDatasetSelectedLine: function(oEvent){
                this.byId("chartContainer").setVizType('line');
            },
            
            onDatasetSelecteColumn: function(oEvent){
                this.byId("chartContainer").setVizType('column');
            },
            
            onDatasetSelecteBullet: function(oEvent){
                this.byId("chartContainer").setVizType('bullet');
            },
            
            onDatasetSelecteArea: function(oEvent){
                this.byId("chartContainer").setVizType('area');
            }
        });
    });

     

    Output

    VizFrame Chart in UI5 using local JSON or OData

  • Download PDF in SAP UI5

    Introduction

    Welcome to a comprehensive guide on “Downloading PDFs in SAP UI5”. If you’ve ever grappled with the task of managing PDF files within your SAP UI5 applications, you’re in the right place. This tutorial will break down the process, providing you with an easy-to-follow method to implement this feature. Learn how to facilitate seamless PDF downloads, enhancing the user experience and functionality of your SAP UI5 application. So, whether you’re a seasoned developer or just starting out, this guide will help you master the process of PDF downloads in SAP UI5.

    How to Download PDF using JavaScript

    If you want to download a PDF file using JavaScript, you can use the built-in fetch API to retrieve the file from the server and then create a Blob from the response. After that, you can create a link element and simulate a click on it to start the download. Here are the steps:

    1. Make an HTTP request for the file: You can use the fetch API, which returns a promise that resolves to the Response to that request, whether it is successful or not.

    2. Read the response as a Blob: The response object resulting from the fetch request contains several methods to read the body in various formats. You can use `response.blob()` to read the response as a Blob which represents the PDF file.

    3. Create an object URL representing the Blob: Once you have the Blob, you can create an object URL for it using `URL.createObjectURL(blob)`. This will return a URL representing the blob, which you can use to link to the file.

    4. Simulate a link click to download the file: Now you can create a new link element, set its `href` attribute to the object URL, and simulate a click on it. This will start the download of the file.

    5. Revoke the object URL: After starting the download, it’s a good practice to revoke the object URL with `URL.revokeObjectURL(objectUrl)` to free up memory.

    Please note, if you’re going to implement it on a webpage, make sure the server is configured to allow such downloads, the correct CORS headers are set, and the file is available to be fetched and downloaded. This method should work in most modern browsers.

    Download PDF in SAP UI5

    View

    <mvc:View controllerName="pdfDownload.pdfDownload.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="My Project Ideas: Download PDF in UI5">
                        <content>
                            <Link id="downloadLink" text="Download PDF" press="onDownloadPDF"/>
                            <PDFViewer id="pdfViewer" source="https://www.africau.edu/images/default/sample.pdf" width="100%" height="600px"/>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("pdfDownload.pdfDownload.controller.Main", {
            onInit: function () {
    
            },
    
            onDownloadPDF: function () {
                // Replace with the actual URL of the PDF file or get it from OData
                var pdfURL = "https://www.africau.edu/images/default/sample.pdf";
                var link = document.createElement("a");
                link.href = pdfURL;
                link.target = "_blank";
                link.download = "document.pdf";
                link.click();
            }
        });
    });

     

    Output

    Download PDF in SAP UI5

  • Multiupload multiple files one by one in SAP UI5 (Sync Multiple Files Upload)

    Introduction

    Boost your productivity with the power of synchronous multiple file upload in SAP UI5. With our innovative solution, you can easily and efficiently upload multiple files one by one, simplifying your workflow and saving valuable time. Say goodbye to the hassle of uploading files individually and embrace the convenience of synchronous file uploads. Streamline your processes, enhance collaboration, and improve efficiency with Sync Multiple Files Upload in SAP UI5. Experience a seamless and optimized file uploading experience like never before.

    Difference between Sync and Async File Uploads in JavaScript

    Synchronous (Sync) and asynchronous (Async) file uploads in JavaScript refer to two different approaches for handling file upload operations. Here’s a breakdown of the key differences between the two:

    1. Execution Flow:
    – Sync: In synchronous file uploads, the execution of code pauses until the file upload operation is complete. It means that other code or operations won’t execute until the upload is finished.
    – Async: Asynchronous file uploads, on the other hand, allow the execution of code to continue while the file upload operation is in progress. The code doesn’t block and waits for the upload to complete.

    2. User Experience:
    – Sync: Synchronous file uploads can potentially cause the user interface to freeze or become unresponsive during the upload process. This is because the entire upload operation blocks the execution of other code or user interactions until it finishes.
    – Async: Asynchronous file uploads provide a better user experience as they allow the user interface to remain responsive while the upload is happening. Users can continue interacting with the application without any interruptions.

    3. Code Structure:
    – Sync: Synchronous file upload code is typically written in a linear and sequential manner. The code execution waits for the upload to complete before proceeding to the next line of code.
    – Async: Asynchronous file upload code is structured using callbacks, promises, or async/await syntax. It allows for non-blocking execution, enabling other code or operations to run concurrently while the upload progresses.

    4. Scalability and Performance:
    – Sync: Synchronous file uploads may not be suitable for large file uploads or scenarios with high concurrency. They can impact the scalability and performance of the application, especially if multiple users are uploading files simultaneously.
    – Async: Asynchronous file uploads are more scalable and performant as they allow for concurrent execution of multiple operations. This is particularly beneficial when dealing with large file uploads or multiple users uploading files concurrently.

    5. Error Handling:
    – Sync: Synchronous file uploads often handle errors using exception handling mechanisms. If an error occurs during the upload process, it can lead to program crashes or disruptions in the code flow.
    – Async: Asynchronous file uploads provide better error handling capabilities. They allow for the use of error callbacks, rejection handling in promises, or try-catch blocks with async/await, enabling more graceful error handling and recovery options.

    In summary, synchronous file uploads block the execution of other code until the upload is complete, while asynchronous file uploads allow concurrent execution, providing a better user experience, scalability, and performance. Asynchronous approaches are typically preferred for modern web applications where responsiveness and efficiency are crucial.

    When to choose Sync File Upload?

    Synchronous file uploads can be appropriate in certain scenarios where the following conditions are met:

    1. Simplicity: If the file upload operation is simple and doesn’t involve complex processing or interactions with other parts of the application, synchronous file uploads can be a straightforward solution. They have a linear code structure, making it easier to understand and implement.

    2. Small File Sizes: Synchronous file uploads can be suitable for small file sizes that can be uploaded quickly without causing significant delays or freezing the user interface. If the file sizes are small and the upload process is expected to complete rapidly, synchronous uploads may be sufficient.

    3. Sequential Dependencies: If the file upload operation depends on the completion of other synchronous tasks or operations in your application, a synchronous approach can simplify the coordination between these steps. For example, if the file upload is tightly linked with specific data processing or validation steps that must occur sequentially, synchronous file uploads can ensure the proper order of execution.

    4. Simultaneous Blocking: In some cases, blocking the user interface during the file upload might be desired. For instance, in certain security-conscious applications where it is crucial to ensure that no other actions can be performed while the file is being uploaded, synchronous file uploads can be employed.

    It’s important to note that synchronous file uploads may not be suitable for scenarios involving large file sizes, complex operations, or situations where multiple users are simultaneously uploading files. In such cases, asynchronous file uploads are generally preferred to maintain a responsive user interface and better scalability.

    Multiupload multiple files one by one in SAP UI5 (Sync Multiple Files Upload)

    View Code

    <mvc:View controllerName="TestProject.TestProject.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
    <Shell id="shell">
    <App id="app">
    <pages>
    <Page id="page" title="My Project Ideas: Multiupload multiple files one by one in UI5 (Sync Multiple Upload files)">
    <content>
    <UploadCollection id="idMultiUploader" maximumFilenameLength="55" maximumFileSize="3" multiple="true" sameFilenameAllowed="false"
    instantUpload="false" noDataDescription="{i18n>noDataDescriptiont}" change="onChangeEmailUpload" fileDeleted="onFileDeleted"
    filenameLengthExceed="onFilenameLengthExceed" fileSizeExceed="onFileSizeExceed" typeMissmatch="onTypeMissmatchMultiUpload"
    uploadComplete="onUploadComplete" beforeUploadStarts="onBeforeUploadStarts"/>
    <Button text="{i18n>Upload}" press="onMultiUploadSubmit"/>
    <Button id="messagePopoverBtn" icon="sap-icon://message-popup" type="{popoverModel>/type}" text="{popoverModel>/messagesLength}"
    press="handleMessagePopoverPress"/>
    </content>
    </Page>
    </pages>
    </App>
    </Shell>
    </mvc:View>

     

    Controller Code

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/ui/core/BusyIndicator",
        "sap/m/MessageBox",
        "sap/m/MessagePopover",
        "sap/m/MessagePopoverItem",
        "sap/m/Button"
    ], function (Controller, BusyIndicator, MessageBox, MessagePopover, MessagePopoverItem, Button) {
        "use strict";
        var oMessageTemplate;
        var oMessagePopover;
        return Controller.extend("TestProject.TestProject.controller.Main", {
            onInit: function () {
                var headerButton = new sap.m.Button({
                    text: "Clear",
                    type: sap.m.ButtonType.Reject,
                    press: function () {
                        that.onClearNotification();
                    }
                });
                oMessageTemplate = new MessagePopoverItem({
                    type: '{T}',
                    title: '{S}',
                });
                oMessagePopover = new MessagePopover({
                    items: {
                        path: '/',
                        template: oMessageTemplate
                    },
                    headerButton: headerButton
                });
                var pop_msgModel = new sap.ui.model.json.JSONModel({
                    "messagesLength": "",
                    "type": "Default"
                });
                this.getView().setModel(pop_msgModel, "popoverModel");
                var popModel = new sap.ui.model.json.JSONModel({});
                oMessagePopover.setModel(popModel);
                // Uploader Files
                this.contentFiles = [];
                this.contentSize = 0;
            },
    
            /**
             * onUploadContentTable is invoked on click from UI. 
             * Input: Excel Data
             * Output: Excel Preview
             * Excel upload is implemented in BaseController.js
             */
    
            onUploadContentTable: function (oEvent) {
                BusyIndicator.show();
                this.file = oEvent.getParameter("files")[0];
                this.UploadUrl = "/DataManager/masterData/contentTable";
                this.getExcelPreview(this.file, oEvent);
                this.byId("uploadContentTableTemplate").setValue("");
                BusyIndicator.hide();
            },
    
            /**
             * onMultiUploadCancel is invoked on click from UI. 
             * Input: oEvent
             * Output: Deletion of all Items of Dialog Box and Dialog Box closes
             */
    
            onMultiUploadCancel: function (oEvent) {},
    
            /**
             * onChangeEmailUpload is invoked on drag and drop of files. 
             * Input: Single or Multiple Excel Data
             * Output: All files are added within an array and used during submit
             */
    
            onChangeEmailUpload: function (oEvent) {
                var that = this;
                if (oEvent.getParameters("files").files[0]) {
                    // if files added via add button
                    var allData = Object.values(oEvent.getParameters("files").files);
                    allData.forEach(function (data) {
                        that.contentFiles = that.contentFiles.concat(data);
                    });
                } else {
                    // if files added via drag and drop
                    this.contentFiles = this.contentFiles.concat(oEvent.getParameter("files"));
                }
            },
    
            /**
             * onMultiUploadSubmit is invoked on click from UI. 
             * Input: Single or Multiple Excel Data
             * Output: Messages in Popover
             * Table rebind is implemented in BaseController.js
             * It is a recurring function that uploads file on every succcess of previous one
             */
    
            onMultiUploadSubmit: function (oEvent, index) {
                var that = this;
                var formData;
                var sPercentage;
                this.UploadUrl = "/DataManager/masterData/contentTable";
                BusyIndicator.show(0);
                if (!index) {
                    index = 0;
                    // Progress Bar to show upload in percentage
                    if (!that._oProgressDialog) {
                        that._oProgressDialog = sap.ui.xmlfragment("TestProject.TestProject.fragment.progressIndicator", that);
                        that.getView().addDependent(that._oProgressDialog);
                    }
                    that._oProgressDialog.open();
                }
                if (that.contentFiles.length > 0 && index < that.contentFiles.length) {
                    formData = that.contentFiles[index];
                    var form = new FormData();
                    form.append("file", formData);
                    return $.ajax({
                        method: "PUT",
                        url: "/DataManager/masterData/contentTable",
                        data: form,
                        async: true,
                        processData: false,
                        mimeType: "multipart/form-data",
                        headers: {
                            "X-Csrf-Token": "<Get token from Data Model>"
                        },
                        contentType: false,
                    }).done((response) => {
                        var successData = [];
                        successData.push({
                            T: "Success",
                            S: that.contentFiles[index].name + " : " + response
                        });
                        // Updating the Message Popover
                        var previous = oMessagePopover.getModel().getData();
                        if (previous.length === undefined)
                            previous = [];
                        var updated = previous != "" ? previous.concat(successData) : successData;
                        oMessagePopover.getModel().setData(updated);
                        oMessagePopover.getModel().refresh(true);
                        that.getView().getModel("popoverModel").getData().messagesLength = updated.length;
                        that.getView().getModel("popoverModel").getData().type = "Emphasized";
                        that.getView().getModel("popoverModel").refresh(true);
                        // Updating the progress Indicator
                        sPercentage = parseInt(((index + 1) / that.contentFiles.length) * 100, 0);
                        that.getOwnerComponent().getModel("appConfigModel").setProperty("/uploadPercentage", sPercentage);
                        that.onMultiUploadSubmit(oEvent, index + 1);
                    }).fail(function (XMLHttpRequest, textStatus, errorThrown) {
                        // Updating the Message Popover
                        var sErrorMsg = that.getErrorMsg(XMLHttpRequest, textStatus, errorThrown);
                        if (sErrorMsg) {
                            var errorData = [];
                            errorData.push({
                                T: "Error",
                                S: that.contentFiles[index].name + " : " + sErrorMsg
                            });
                            var previous = oMessagePopover.getModel().getData();
                            if (previous.length === undefined)
                                previous = [];
                            var updated = previous != "" ? previous.concat(errorData) : errorData;
                            oMessagePopover.getModel().setData(updated);
                            oMessagePopover.getModel().refresh(true);
                            that.getView().getModel("popoverModel").getData().messagesLength = updated.length;
                            that.getView().getModel("popoverModel").getData().type = "Emphasized";
                            that.getView().getModel("popoverModel").refresh(true);
                            // Updating the progress Indicator
                            sPercentage = parseInt(((index + 1) / that.contentFiles.length) * 100, 0);
                            that.getOwnerComponent().getModel("appConfigModel").setProperty("/uploadPercentage", sPercentage);
                            that.onMultiUploadSubmit(oEvent, index + 1);
                        }
                    });
                } else {
                    that.contentFiles = [];
                    BusyIndicator.hide();
                    // Updating the progress Indicator
                    sPercentage = parseInt(((index + 1) / that.contentFiles.length) * 100, 0);
                    that.getOwnerComponent().getModel("appConfigModel").setProperty("/uploadPercentage", sPercentage);
                    that._oProgressDialog.close();
                }
            },
    
            /**
             * handleMessagePopoverPress is invoked on click from UI. 
             * Input: oEvent
             * Output: Message Popover opens up or closes
             */
    
            handleMessagePopoverPress: function (oEvent) {
                oMessagePopover.toggle(oEvent.getSource());
            },
    
            /**
             * onFileSizeExceed is invoked on click of Upload in UI. 
             * Input: Size of file
             * Output: Error Message
             */
    
            onFileSizeExceed: function (oEvent) {
                // read msg from i18n model
                var sMsg = this.oBundle.getText("MultiUploadCondition");
                MessageBox.error(sMsg);
            },
    
            /**
             * onTypeMissmatchMultiUpload is invoked click of Upload in UI. 
             * Input: Type of file
             * Output: Error Message
             * The type miss match generic function is available in base controller
             */
    
            onTypeMissmatchMultiUpload: function (oEvent) {
                // this.onTypeMissmatch();
            },
    
            /**
             * onClearNotification is invoked on click of Clear from UI. 
             * Input: Message Model
             * Output: Empty Message Model
             */
    
            onClearNotification: function (oEvent) {
                // Clear Popover Messages
                this.getView().getModel("popoverModel").setData({
                    "messagesLength": "",
                    "type": "Default"
                });
                this.getView().getModel("popoverModel").refresh(true);
                oMessagePopover.getModel().setData("");
                oMessagePopover.getModel().refresh(true);
            },
    
            /**
             * onResetForms is invoked from a function. 
             * Input: array, object or string
             * Output: Input field value is cleared
             */
    
            getErrorMsg: function (XMLHttpRequest, textStatus, errorThrown) {
                var sCommonErrorMsg = "An error caught";
                var sTimeOutErrorMsg = "Time out";
                var sErrorMsg;
                if (XMLHttpRequest.responseJSON) {
                    if (XMLHttpRequest.responseJSON.message) {
                        if (Array.isArray(XMLHttpRequest.responseJSON.message)) {
                            sErrorMsg = XMLHttpRequest.responseJSON.message.join("\n");
                        } else {
                            sErrorMsg = XMLHttpRequest.responseJSON.message;
                        }
                    } else {
                        sErrorMsg = XMLHttpRequest.responseJSON.error;
                    }
                } else if (XMLHttpRequest.responseText) {
                    if (XMLHttpRequest.responseText == "Unauthorized") {
                        sErrorMsg = sTimeOutErrorMsg;
                        window.location.href = '../logout';
                    } else {
                        sErrorMsg = XMLHttpRequest.responseText;
                    }
                } else {
                    sErrorMsg = sCommonErrorMsg;
                }
                return sErrorMsg;
            }
        });
    });

     

    progressIndicator.fragment.xml Code

    <core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml">
        <Dialog id="idProgresIndicatorDialog" title="{i18n>UploadinProgress}" titleAlignment="Center" showHeader="true"
            class="sapUiResponsivePadding">
            <ProgressIndicator id="idProgresIndicator" class="sapUiSmallMarginBottom" displayValue="{appConfigModel>/uploadPercentage}%"
                percentValue="{appConfigModel>/uploadPercentage}" state="Information" displayOnly="true"/>
        </Dialog>
    </core:FragmentDefinition>

     

    Model Code

    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;
            },
            
            createAppConfigData: function () {
                var oAppConfigModel = {
                    "uploadPercentage": 0
                };
                return oAppConfigModel;
            }
    
        };
    });

     

    Component.js Code

    sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/Device",
        "TestProject/TestProject/model/models",
        "sap/ui/model/json/JSONModel",
    ], function (UIComponent, Device, models, JSONModel) {
        "use strict";
    
        return UIComponent.extend("TestProject.TestProject.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 AppConfigModel
                this.setModel(new JSONModel(models.createAppConfigData()), "appConfigModel");
            }
        });
    });

     

    Output

    Before Upload

    Multiupload multiple files one by one in SAP UI5 Before Upload

    Progress Indicator

    Progress Indicator

    After Upload

    Sync Multiple Files Upload

     

    Note: Update i18n wherever you see the wrong texts, they are intended to be shown like that in the absence of i18n files

  • Multiupload multiple files simultaneously in UI5 (Async Multiple Upload files)

    Introduction

    Introducing Multiupload: the ultimate solution for uploading multiple files simultaneously in SAP UI5. With our Async Multiple Upload feature, you can easily select and upload multiple files in one go, saving you time and effort. Whether you need to upload documents, images, or any other file types, Multiupload streamlines the process, ensuring a smooth and efficient file upload experience. Say goodbye to tedious one-by-one uploads and embrace the power of simultaneous file uploading with Multiupload in UI5.

    Difference between Sync and Asyn File Uploads in JavaScript

    Synchronous (Sync) and asynchronous (Async) file uploads in JavaScript refer to different approaches for handling file upload operations.

    1. Synchronous File Upload:
    – In synchronous file upload, the upload process occurs in a blocking manner.
    – When a file is uploaded synchronously, the entire execution of the script is paused until the upload is complete.
    – Users have to wait for the file to be uploaded before they can continue interacting with the webpage.
    – Synchronous file uploads are straightforward to implement but may lead to a poor user experience, especially for larger files or slower network connections.

    2. Asynchronous File Upload:
    – In asynchronous file upload, the upload process occurs in a non-blocking manner.
    – When a file is uploaded asynchronously, the script continues executing without waiting for the upload to complete.
    – Users can continue interacting with the webpage while the file is being uploaded in the background.
    – Asynchronous file uploads are typically implemented using AJAX (Asynchronous JavaScript and XML) techniques, allowing for a smoother user experience.
    – Progress indicators and callbacks can be used to provide real-time feedback to the user during the upload process.

    The choice between synchronous and asynchronous file uploads depends on various factors such as the specific requirements of the application, file size, network conditions, and desired user experience. Asynchronous file uploads are commonly preferred as they allow for better responsiveness and improved user interactions while files are being uploaded.

    Multiupload multiple files simultaneously in UI5 (Async Multiple Upload files)

    View Code

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
        xmlns:upload="sap.m.upload">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page" title="My Project Ideas: Multiupload multiple files simultaneously in UI5 (Async Multiple Upload files)">
                        <content>
                            <upload:UploadSet id="UploadSet" instantUpload="true" showIcons="true" uploadEnabled="true" terminationEnabled="true"
                                fileTypes="txt,doc,png" maxFileNameLength="30" maxFileSize="200" mediaTypes="text/plain,application/msword,image/png"
                                uploadUrl="../../../../upload" items="{path: '/items', templateShareable: false}" mode="MultiSelect" selectionChanged="onSelectionChange">
                                <upload:toolbar>
                                    <OverflowToolbar>
                                        <ToolbarSpacer/>
                                        <Button id="uploadSelectedButton" text="Upload selected" press="onUploadSelectedButton"/>
                                        <Button id="downloadSelectedButton" text="Download selected" press="onDownloadSelectedButton"/>
                                        <Button id="versionButton" enabled="false" text="Upload a new version" press="onVersionUpload"/>
                                        <upload:UploadSetToolbarPlaceholder/>
                                    </OverflowToolbar>
                                </upload:toolbar>
                                <upload:items>
                                    <upload:UploadSetItem fileName="{fileName}" mediaType="{mediaType}" url="{url}" thumbnailUrl="{thumbnailUrl}"
                                        markers="{path: 'markers', templateShareable: false}" statuses="{path: 'statuses', templateShareable: false}" uploadState="{uploadState}">
                                        <upload:markers>
                                            <ObjectMarker type="{type}" visibility="{visibility}"/>
                                        </upload:markers>
                                        <upload:statuses>
                                            <ObjectStatus title="{title}" text="{text}" state="{state}" icon="{icon}" active="{active}"/>
                                        </upload:statuses>
                                    </upload:UploadSetItem>
                                </upload:items>
                            </upload:UploadSet>
                            <VBox>
                                <Title text="Messages"/>
                                <TextArea width="100%" value="{appConfigModel>/msgModel}"/>
                            </VBox>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller Code

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
                var oUploadSet = this.byId("UploadSet");
                // Modify "add file" button
                oUploadSet.getDefaultFileUploader().setButtonOnly(false);
                oUploadSet.getDefaultFileUploader().setTooltip("");
                oUploadSet.getDefaultFileUploader().setIconOnly(true);
                oUploadSet.getDefaultFileUploader().setIcon("sap-icon://attachment");
                oUploadSet.attachUploadCompleted(this.onUploadCompleted.bind(this));
            },
    
            onUploadSelectedButton: function () {
                var that = this;
                // Message Model
                var msgModel = new sap.ui.model.json.JSONModel({});
                var oUploadSet = this.byId("UploadSet");
                var previous;
                oUploadSet.getItems().forEach(function (oItem) {
                    if (oItem.getListItem().getSelected()) {
                        // AJAX Call
                        var form = new FormData();
                        form.append("file", oItem);
                        return $.ajax({
                            method: "PUT",
                            url: "<Your API>",
                            data: form,
                            async: true,
                            processData: false,
                            mimeType: "multipart/form-data",
                            headers: {
                                "X-Csrf-Token": "<get security key from Data Model>"
                            },
                            contentType: false,
                        }).done((response) => {
                            previous = that.getOwnerComponent().getModel("appConfigModel").getProperty("/msgModel");
                            var updated = previous != "" ? previous.concat(response, ', ') : response;
                            that.getOwnerComponent().getModel("appConfigModel").setProperty("/msgModel", updated);
                        }).fail(function (XMLHttpRequest, textStatus, errorThrown) {
                            // Updating the Message Popover
                            var sErrorMsg = XMLHttpRequest.responseText;
                            if (sErrorMsg) {
                                previous = that.getOwnerComponent().getModel("appConfigModel").getProperty("/msgModel");
                                var updated = previous != "" ? previous.concat(sErrorMsg, ', ') : sErrorMsg;
                                that.getOwnerComponent().getModel("appConfigModel").setProperty("/msgModel", updated);
                            }
                        });
                    }
                });
            },
    
            onDownloadSelectedButton: function () {
                var oUploadSet = this.byId("UploadSet");
    
                oUploadSet.getItems().forEach(function (oItem) {
                    if (oItem.getListItem().getSelected()) {
                        oItem.download(true);
                    }
                });
            },
    
            onSelectionChange: function () {
                var oUploadSet = this.byId("UploadSet");
                // If there's any item selected, sets version button enabled
                if (oUploadSet.getSelectedItems().length > 0) {
                    if (oUploadSet.getSelectedItems().length === 1) {
                        this.byId("versionButton").setEnabled(true);
                    } else {
                        this.byId("versionButton").setEnabled(false);
                    }
                } else {
                    this.byId("versionButton").setEnabled(false);
                }
            },
    
            onVersionUpload: function (oEvent) {
                var oUploadSet = this.byId("UploadSet");
                this.oItemToUpdate = oUploadSet.getSelectedItem()[0];
                oUploadSet.openFileDialog(this.oItemToUpdate);
            },
    
            onUploadCompleted: function (oEvent) {
                this.oItemToUpdate = null;
                this.byId("versionButton").setEnabled(false);
            }
        });
    });

    Output

    Multiupload multiple files simultaneously in UI5 (Async Multiple Upload files)

  • Custom Message Popover Integration in SAP UI5

    Introduction

    In this tutorial, we will learn simple steps to implement Custom Message Popover Integration in SAP UI5.

    In SAP UI5, the ability to display informative messages or notifications to users is crucial for enhancing user experience and providing important feedback. Custom Message Popover integration in SAP UI5 allows developers to create and display tailored messages in a visually appealing and interactive manner. By leveraging this feature, developers can effectively communicate messages, warnings, errors, or any other relevant information to users within their applications.

    Custom Message Popover integration in SAP UI5 involves utilizing the sap.m.Popover control to create a popover-like dialog that can be triggered programmatically. This popover can be customized to display messages with different severity levels, such as success, information, warning, or error. Developers have full control over the content, styling, and behavior of the popover, enabling them to design a highly interactive and visually consistent messaging experience.

    In this project, we will explore the process of integrating Custom Message Popover in SAP UI5 applications. We will learn how to define and customize the popover control, define messages with different severity levels, and dynamically populate the popover with relevant content. Additionally, we will explore how to handle user interactions with the popover, such as dismissals or further actions based on the displayed messages.

    By the end of this project, you will have a solid understanding of how to integrate Custom Message Popover in SAP UI5 and leverage its capabilities to deliver informative and visually appealing messages to users. This integration will enhance the usability of your applications and empower users with timely and actionable information, contributing to a more seamless and efficient user experience. So, let’s dive into the world of Custom Message Popover integration in SAP UI5 and unlock the potential to elevate your application’s messaging capabilities.

    What is Message Popover in SAP UI5

    In SAP UI5, a Message Popover is a UI control that provides a convenient and visually appealing way to display messages, notifications, or alerts to users within an application. It serves as a container for displaying multiple messages of different severity levels, such as success, information, warning, or error.

    The Message Popover control in SAP UI5, typically represented as a small dialog or popover-like element, offers a centralized location for presenting important information to users without disrupting their workflow. It allows developers to communicate various types of messages in a concise and organized manner, improving the overall user experience and facilitating effective communication.

    The Message Popover in SAP UI5 provides the following key features:

    1. Message Types and Severity Levels: The Message Popover supports different message types with associated severity levels, enabling developers to categorize and differentiate messages based on their importance or urgency.

    2. Message Aggregation: The Message Popover can aggregate multiple messages, allowing developers to display multiple notifications or alerts simultaneously. Messages can be added or removed dynamically based on application logic or user interactions.

    3. Styling and Formatting: Developers can customize the appearance and styling of the Message Popover to match the overall design language and branding of their application. This includes options to define the layout, colors, icons, and other visual elements.

    4. Interaction and Actionability: Users can interact with messages within the Message Popover by performing actions associated with each message. This can include dismissing a message, acknowledging it, or triggering further actions based on the message content.

    5. Localization and Accessibility: The Message Popover supports localization, allowing developers to display messages in different languages or adapt to regional preferences. It also ensures compliance with accessibility guidelines, making the messages accessible to users with disabilities.

    By leveraging the Message Popover control in SAP UI5, developers can effectively communicate important information, warnings, errors, or any other relevant messages to users in a user-friendly and organized manner. This enhances the usability and user experience of the application by providing timely and actionable feedback.

    Steps for Custom Message Popover Integration in SAP UI5

    Here are the steps for integrating a Custom Message Popover in SAP UI5:

    1. Set up the SAP UI5 Development Environment:
    – Install SAPUI5 library and necessary development tools.
    – Create a new SAP UI5 project or use an existing project as a base.

    2. Define the UI Layout:
    – Create a view or a page where the Message Popover will be displayed.
    – Design the overall layout using SAP UI5 controls like panels, containers, or grids.

    3. Create the Message Popover Control:
    – Instantiate the sap.m.Popover control in your view or page.
    – Configure the popover with desired properties such as width, height, and positioning.

    4. Define Message Models and Data Binding:
    – Define a message model to store the messages to be displayed in the popover.
    – Populate the message model with the relevant messages based on your application logic.
    – Bind the message model to the Message Popover control to dynamically display the messages.

    5. Customize the Message Popover Content:
    – Define the content of the Message Popover control, including the layout and formatting of the messages.
    – Utilize UI5 controls like sap.m.MessageStrip or sap.m.List to display individual messages within the popover.
    – Customize the appearance of the messages based on their severity levels using icons, colors, or formatting.

    6. Handle User Interactions:
    – Implement event handlers or listeners for user interactions with the messages, such as dismissals or further actions.
    – Define appropriate actions based on the user’s response to a message, like acknowledging or resolving the issue.

    7. Displaying the Message Popover:
    – Trigger the display of the Message Popover control based on specific events or application logic.
    – Set the popover’s position relative to a target control or a specific location on the screen.
    – Show or hide the Message Popover dynamically as needed.

    8. Test and Refine:
    – Test the integration of the Custom Message Popover by simulating various scenarios and verifying the display and behavior of messages.
    – Gather feedback from users and iterate on the design and functionality based on their requirements and suggestions.
    – Continuously refine and optimize the Custom Message Popover’s performance, styling, and user experience.

    By following these steps, you can successfully integrate a Custom Message Popover in your SAP UI5 application. This integration will enable you to display informative messages and notifications to users in a visually appealing and interactive manner, enhancing the usability and overall user experience of your application.

    View Code

    <mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:l="sap.ui.layout" height="100%"
        displayBlock="true">
        <Page>
            <customHeader>
                <Bar>
                    <contentLeft>
                        <Button id="msgpop1" icon="sap-icon://message-popup" text="{popoverModel>/messagesLength}" type="{popoverModel>/type}"
                            press="handleMessagePopoverPress"/>
                    </contentLeft>
                    <contentMiddle>
                        <Title text="My Project Ideas: Message Popover Integration in SAP UI5" titleStyle="H2"></Title>
                    </contentMiddle>
                    <contentRight>
                        <Button text="Get Success Message" press="onSuccess" icon="sap-icon://message-success"/>
                        <Button text="Get Error Message" press="onError" icon="sap-icon://message-error"/>
                    </contentRight>
                </Bar>
            </customHeader>
        </Page>
    </mvc:View>

     

    Controller Code

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/MessageBox",
        "sap/m/MessageToast",
        "sap/ui/model/json/JSONModel",
        "sap/ui/Device",
        'sap/m/MessagePopover',
        'sap/m/MessagePopoverItem'
    ], function (Controller, MessageBox, MessageToast, JSONModel, Device, MessagePopover, MessagePopoverItem) {
        "use strict";
    
        var oMessageTemplate = new MessagePopoverItem({
            type: '{T}',
            title: '{S}',
        });
    
        var oMessagePopover = new MessagePopover({
            items: {
                path: '/',
                template: oMessageTemplate
            }
        });
    
        return Controller.extend("Test.Test.controller.Main", {
            onInit: function () {
                var that = this;
                var pop_msgModel = new sap.ui.model.json.JSONModel({
                    "messagesLength": "",
                    "type": "Default"
                });
                this.getView().setModel(pop_msgModel, "popoverModel");
                var popModel = new sap.ui.model.json.JSONModel({});
                oMessagePopover.setModel(popModel);
            },
    
            onSuccess: function () {
                var that = this;
                var message = "This is a success message!";
                var w_data = [];
                w_data.push({
                    T: "Success",
                    S: message
                });
                var previous = oMessagePopover.getModel().getData();
                if (previous.length === undefined)
                    previous = [];
                var updated = previous !== "" ? previous.concat(w_data) : w_data
                oMessagePopover.getModel().setData(updated);
                oMessagePopover.getModel().refresh(true);
                that.getView().getModel("popoverModel").getData().messagesLength = updated.length;
                that.getView().getModel("popoverModel").getData().type = "Emphasized";
                that.getView().getModel("popoverModel").refresh(true);
            },
    
            onError: function () {
                var that = this;
                var message = "This is an error message!";
                var w_data = [];
                w_data.push({
                    T: "Error",
                    S: message
                });
                var previous = oMessagePopover.getModel().getData();
                if (previous.length === undefined)
                    previous = [];
                var updated = previous !== "" ? previous.concat(w_data) : w_data
                oMessagePopover.getModel().setData(updated);
                oMessagePopover.getModel().refresh(true);
                that.getView().getModel("popoverModel").getData().messagesLength = updated.length;
                that.getView().getModel("popoverModel").getData().type = "Emphasized";
                that.getView().getModel("popoverModel").refresh(true);
            },
    
            handleMessagePopoverPress: function (oEvent) {
                oMessagePopover.toggle(oEvent.getSource());
            }
        });
    });

     

    Output

    Custom Message Popover Integration in SAP UI5