Skip to Content
Technical Articles
Author's profile photo Vitor Eduardo Seifert Bazzo

Adaptation Project: Freestyle SAPUI5 App – Adding a Search Link to Items on a Table

Introduction

After we have adapted an SAP Fiori elements application in my last blog post, today we are going to make changes to a freestyle SAPUI5 application. Before you proceed, please make sure you understand the different capabilities of SAPUI5 Flexibility by reading this blog.

We will start with a purchasing app and add a custom column to an existing table of products. This column will contain a link to a Google search for the corresponding product so that the end user can quickly access more information about it. Let’s briefly review how to create an Adaptation Project in SAP Business Application Studio (BAS) and then implement the extension using Visual Editor.

Target Audience: Developers who want to compatibly adapt and extend existing freestyle applications by changing their appearance and/or functionality.

Creating the Adaptation Project and Starting the Visual Editor

SAP Business Application Studio is an SAP Business Technology Platform (BTP) service that offers a development environment optimized for business applications. Please refer to the sections Creating the Adaptation Project in SAP Business Application Studio and Working with the SAPUI5 Visual Editor in my last blog post and follow the steps described there. I named the project for this example OrderProducts.adapt. Once you are in the editor, you can proceed to the next section. The app we will be adapting originally looks like this:

Application before adaptation

Adding the XML Fragments

In this application, we are dealing with an sap.m.Table (Responsive Table). To learn about the structure of this table (or any other standard control) and to help you decide how to make your changes, you can check the SAPUI5 Samples and API Reference.

From the documentation, we learn that the column header (title) should be an extension of the columns aggregation on the table while the link itself should be added to each line of the table, using aggregation cells – which are bound to the table items (products). This way the column header will always be present and static while the link for each item will be dynamic (triggering the search for the corresponding product name).

Both the column and the cell will be new XML fragments on the application. To add a fragment, we need to make a change to an existing control. Let’s start with the column: In Edit mode, on the table and choose Add Fragment.

Add fragment to table

In the pop-up we need to select the Target Aggregation and the index (position in the aggregation) for the new fragment. In our example we use the Columns aggregation and the index 10 – so the column will be added at the end. We only see six columns in the screenshot – that’s because some columns are hidden. Click on Create New and choose a name for our fragment. Let’s call it MoreInformationColumn. This will create a new change on the /webapp/changes folder and a new file called MoreInformationColumn.fragment.xml in the /webapp/changes/fragments folder. Before we start modifying the XML, notice the comment on the first line: Use stable and unique IDs! When working with SAPUI5 Flexibility, it is very important to understand and use stable IDs. More details on the topic can be found here.

We already learned about internationalization and resource bundles in my previous blog post, so let’s create the XML fragment already with translatable texts. The MoreInformationColumn.fragment.xml file should look like this – the column properties were copied from the other columns in the table, so they all have the same appearance:

<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Column id="moreInformationColumn"
        width="12em"
        hAlign="Right"
        styleClass="sapRTSTOrdProdColumnProductTable"
        vAlign="Middle">
        <Text id="moreInformationColumnHeaderText" text="{i18n>MORE_INFORMATION_COLUMN_HEADER}" />
    </Column>
</core:FragmentDefinition>

Add the following lines to the /i18n/i18.properties file:

# More Information Column
MORE_INFORMATION_COLUMN_HEADER=More Info

Once the fragment is finalized, restart the Visual Editor to see the new column header. However, the content is still missing. Let’s take care of that next.

Application%20with%20new%20column

Application with new column

If we click on any of the line items on the table, all the items are selected. This is because we are selecting an aggregation binding – meaning the items are generated based on the underlying data. As our link should also be displayed on each line and refer to the item on that line, our next fragment should be added to this aggregation. Right-click on any line and select Add Fragment:

Add%20fragment%20to%20items

Add fragment to items

The proposed aggregation – cells – is the one we are looking for and the index should be the same which was chosen for the table (in our example, 10). Click on Create new – let’s call it SearchLink. This fragment is very simple – it only contains a link with a text.

<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Link id="searchLink" text="{i18n>SEARCH_LINK}"/>
</core:FragmentDefinition>

Add the following lines to the /i18n/i18.properties file:

# More Information Column
SEARCH_LINK=Search in Google

If we restart the Visual Editor, the line items will now contain links. If we click on them, nothing happens – because we still need to define their behavior. This is done using a Controller Extension.

Column%20with%20link

Column with link

Add the Custom Controller Extension

On the editor, right-click on the view and select Extend with Controller. We enter a name for our controller and choose Extend.

Adding%20a%20controller%20extension

Adding a controller extension

For this example, let’s use SearchLinkImplementation. The file will be created in the /webapp/changes/coding/ folder. The editor will open it automatically. The controller extension is created with guidelines to support with the implementation. For the sake of brevity, these comments have been removed in the example below, leaving only the code necessary for our functionality:

sap.ui.define([
    'sap/ui/core/mvc/ControllerExtension',
    'sap/m/library'
    ],
    function (
        ControllerExtension,
        mobileLibrary
    ) {
        "use strict";
        return ControllerExtension.extend("OrderProducts.adapt.SearchLinkImplementation", {
            handleLinkPress: function(oEvent) {
                var oClickedLink = oEvent.oSource;
                var oBindingContext = oClickedLink.getBindingContext();
                var sProductName = oBindingContext.getObject().ProductName;
                var sTargetURL = "https://www.google.com/search?q=" + sProductName;
                var oURLHelper = mobileLibrary.URLHelper;
                oURLHelper.redirect(sTargetURL, /*bNewWindow =*/ true);
            }
        });
    });

We want the link to trigger a custom function that opens a search link with the product name in a new tab. From the sap.m.Link API documentation, we find that the event for clicking on the link is called “press”. We can declare an event handler for it in the controller extension. The event handler receives the event as a parameter and we can use it to retrieve the exact control that was clicked (oClickedLink).

Now we want to retrieve the product name, which is coming from the data bound to the items. As the link is part of a binding template, we can use getBindingContext() to retrieve information about it. With the binding context, call getObject() to get the actual data item related to the link and finally read the ProductName property.

Now that we have the product name, we can focus on triggering the search. To handle the opening of the Google search link in another tab, we will use the URLHelper control (API reference) from the sap.m library. The target URL is built using the product name previously retrieved and we can finally call the redirect method to open the URL. If the second parameter is “true”, it opens in a new window.

The last step is to connect the link control to this event handler. This is done on the XML fragment. The fragment needs to know where to look for the function, so we must make sure that the path is prefixed with “.extension.” and the namespace of the controller (as described in the documentation):

<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Link id="searchLink" text="{i18n>SEARCH_LINK}" press=".extension.OriginalOrderProducts.adapt.SearchLinkImplementation.handleLinkPress"/>
</core:FragmentDefinition>

And we are done! If we reload the application and click on a link, a new tab will open with a Google search for the product name. If you have difficulties, you can find more information about testing applications and debugging inside the Visual Editor in my previous blog post.

Wrap Up and Further Steps

In this article we went through another simple example of an extension done using Adaptation Project, this time for a freestyle application. Don’t forget to check the other available tutorials and courses provided by SAP and keep an eye on this blog as we will be updating with further resources as soon as they are available.

I would like to thank Dominik Stork, Hristo Tsolev, Mikhail Benderskiy and Oliver Mueller for helping prepare and review the content of this post.

We would love to hear from you! Please leave your feedback below – and let us know which topic you’d like to see next.

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Bhavik Mehta
      Bhavik Mehta

      Hi Vitor,

      Really good blog on Adaptation Project for Free Style Apps. I had few questions though.

      1. Previously when we used Webide we had extension points which were provided by SAP and we use to use the same for adding new fields using fragments. In above e.g. you just directly added new column without referring to extension point does it mean we can add any UI at any given point.
      2. Also previously we had options to replace View and controller in Webide, where we can hack and reimplement SAP provided Functions and UI controls. Is that possible with adaptation project.

      Thanks,

      Bhavik

      Author's profile photo Hristo Tsolev
      Hristo Tsolev

      Hi Bhavik,

       

      1: Yes, you can now add fragments to both extension points (where available) and control aggregations. You can check the official documentation for that here: https://help.sap.com/docs/SAP%20Business%20Application%20Studio/584e0bcbfd4a4aff91c815cefa0bce2d/81df9ddca84f4e248fc521f2e629bba8.html

       

      2. You can add controller extension, but you cannot 'replace' the original controller or replace a View with another one. Though you should be able technically to remove everything that you do not need from a certain view and add the all the needed fragments as mentioned in point 1.

       

      Regards,

      Hristo

      Author's profile photo Quoc Vuong Ho
      Quoc Vuong Ho

      It's good to refresh my knowledge with your blog. Thanks Vitor Eduardo Seifert Bazzo .