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

What will be covered in the article:

  • Enhance oData service with new fields
  • Change XML views of standard Fiori app
  • Adapt JavaScript code for your needs

There are some typical use cases of enhancing Fiori apps. Most of the sources draw attention only to one part of Adaptation projects. That’s why the decision was made to combine backend & frontend work steps in one manual.


Prerequisites:


First off all let’s assume that you received functional specification to adapt F3365 Fiori app (Record Inspection Results in Table Form).

 

Where to start? Google of course!

In the top of the search list you can find the link looks like

https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps('F3365')

You can replace F3365 to any App ID you received from functional

 

Now Go to  IMPLEMENTATION INFORMATION -> Configuration 

01-Fiori-App-Config.png

 

Here we need Technical Name (QM_MLTPL_RR_S1) & SAP UI5 Component (i2d.qm.inspmltpl.resultsrecords1)

Why do we need a technical name? To read XML & JS code. Of course sometimes you can do it directly in a browser. But is better to read all comments in JS code.

Launch /UI5/UI5_REPOSITORY_LOAD program (or BSP_UPDATE_MIMEREPOS in older systems) & download app code to any folder.

02-UI5-UI5_REPOSITORY_LOAD.png

 

Here the 2 most important folders are:

  • controller\

*-dbg.controller.js  non minimized ordinary JS code with comments

  • view\

XML views. Also in sub folder \view\fragments\ some dynamic objects like dialogs and other reusable UI parts are located there.

Another important file is manifest.json but let’s talk about it next time


Now let’s launch Fiori launchpad & find the F3365 app

Before launching app press F12(or Ctrl+Shift+I) & type batch word in the Network tab

03-Fiori-App-URL.png

 

If you noticed in the address bar there is no /sap/bc/ui5_ui5/sap/qm_mltpl_rr_s1 (Path to ICF Node in the 1st screenshot). This path used indirectly via special mechanism & in the URL you can see InspectionCharacteristic-recordMltplResults (so called Semantic Object-Action). We later use this data to create our own tile in Fiori launchpad.

For now lets open batch request in the new tab & replace

$batch?sap-client=200

With GET request from the Payload tab

C_InspLotMltplRsltRec?sap-client=200&$skip=0&$top=20

The URL will look like

/sap/opu/odata/sap/QM_MLTPLRR_SRV/C_InspLotMltplRsltRec?sap-client=200&$skip=0&$top=20

Let’s try to analyze it the result

04-URL-XML.png

 

More or less readable, but probably XML is not the easiest format to understand the actual data.

Now just &$format=json to the end of the URL

05-URL-JSON.png

Is it a little easier than XML? If not then just install Chrome’s or Edge's JSON Formatter plugin first


And now when we see the data from backend we can  return to the agenda:

  • How to enhance oData service with new fields?

If we go back the URL

/sap/opu/odata/sap/QM_MLTPLRR_SRV/C_InspLotMltplRsltRec?sap-client=200&$skip=0&$top=20&$format=json

the most astute one already guess that C_InspLotMltplRsltRec is a CDS. But let’s check it. If we try to open QM_MLTPLRR in Eclipse (Ctrl+Shigt+A)

06-SEGW.png

Yes it is CDS reference based SEGW project.

 

For RAP & CDS referenced projects we can add can extend CDS by SQL

07-CDS-SQL.png

Usually it’s necessary to some kind of texts using system language ($session.system_language). Just don’t forget to ZZ* prefix for custom fields 😊 for safety reason.

 

               But what if SQL is not enough and we have to use ABAP for newly created fields?

08-CDS-ABAP.png

  • For CDS referenced projects there are DPC_EXT classes where we can override GET_ENTITYSET method for the CDS

In the method we need only fill ZZ_HasDiff field.

The definition of C_InspLotMltplRsltRec will already contain newly created custom field

 

Let's check result in the browser

09-JSON-RESULT.png


The new field is ready. How to display it in sap.m.Table?

It's time to create Fiori Adaptation Project

But before that we have to install 1 particular generator VS Code

press Ctrl+Shift+P & type explore ...

10-INSTALL-PLUGIN.png

After installation just press Ctrl+Shift+P again & type Adaptation ...

11-NEW-PROJECT.png

The Namespace is always start with customer.* & is not necessary to start Project with Z*. But for clarity is better to start with Z*. In ABAP terminology the Namespace is kind of enhancement for a Fiori application. And developer can create several of namespaces that do not overlap with each other.

In the next just type Fiori app & press Finish

12-APP-FINISH-WIZARD.png

 

In NPM scripts just launch start-editor

13-START-EDITOR.png

The good thing is that we easily add new Fragments in editor

14-ADD-FRAGMENT.png

The bad news is that for most of the tree we can't add fragments because someone forgot to name the XML view.

15-GREY-TREE.png

That’s why they are greyed in the tree.

What we can do?

  • Use solely JS code (Extend with controller)
  • Try to enhance sap.m.Table with *.change files regardless of the name (the *.change files are generated by Adaptation UI editor)

16-NAME.png

The structure of *.change files is pretty simple. And we can use the 2nd approach. Just use it from another project or view & adjust some of the fields.

The most important one is a selector. By default Fiori adaption editor uses global names(idIsLocal: true)

Let’s start from the simple button in the toolbar

17-CHANGE-FILE.png

Selectors with “__xmlview1--” do not look like firm, but they are work

\webapp\changes\fragments\fragToolbar.fragment.xml

 

<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Button id="custBtWriteDiff" text="Overwrite difference"
            enabled="false"
            press=".extension.customer.zqmu0001.contPage.onBtWriteDiff"/>
</core:FragmentDefinition>

 

Controller extension is not created yet but the new button is visible now

18-NEW-BUTTON.png

 

Now we are ready to a new column & a cell to our project

19-ADD-CELL-COLUMN.png

New sap.m.Column

 

<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Column id="custDiffColumn">
        <Text id="custDiffText" text="Difference" />
    </Column>
</core:FragmentDefinition>

 

& new cell

 

<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
   <ObjectStatus
        id="custDiffValue"
        class="sapUiSmallMarginBottom"
        
        icon ="{= ${ZZ_HasDiff} === 'I' ? 'sap-icon://message-success': ${ZZ_HasDiff} === 'W' ? '' : 'sap-icon://cancel' }"
        active="false"/>
         
</core:FragmentDefinition>

 

But if we check $batch request now we still cannot ZZ_HasDiff in it.

Why? Because they statically requested in the view itself.

20-XML-VEW.png

Let’s add new field via Controller extension

In adaptation mode just right click on desired view & select Extend With Controller

21-ADD-CONTR.png

In UI5 inspector we can find inspectionLotSmartTable (sap.ui.comp.smarttable.SmartTable)

And we need to change its property requestAtLeastFields

22.png

Most of the code can be written without extra JS knowledge. Just find control in UI5 Inspector & find specific event in https://sapui5.hana.ondemand.com/#/api

 

const mainTable = this.getView().byId('inspectionLotTable')

// Set enable button 'Write Difference'
mainTable.attachSelectionChange(() => {
    const button = this.getView().byId('customer.zqmu0001.custBtWriteDiff')
    const oSelectedInspectionLots = mainTable.getSelectedItems();

    button.setEnabled(oSelectedInspectionLots.length > 0 && mainTable.getMode() === sap.m.ListMode.MultiSelect)
})

 

 

Very often we need to implement some actions after DB manipulation. To set a “handler” to CRUD operation 1st of all we have to access parent controller this.base & then call following sequence getOwnerComponent().getModel() to get a model.

 

// Refresh main table when characteristics are saved
this.base.getNewODataModel().attachRequestCompleted(function (oEvent) {
    if (oEvent.getParameter('url') === 'C_InspResultMltplRsltRec' &&
        oEvent.getParameter('method') === 'POST' &&
        oEvent.getParameter('success'))
        mainTable.getBinding("items").refresh();
})

 

where getNewODataModel is declared in BaseController-dbg.js

 

getNewODataModel: function () {
            return this.getOwnerComponent().getModel();
}

 

In event parameters all necessary information is passed to handler. Just write

 

console.log(oEvent.mParameters);

 

to see them all.


UI5 Inspector helps with XML view a lot. But how to enhance JS code?

Just press F12 in Chrome again & put break-points in the Source tab & try to understand existing code. Let’s assume we spent some time & found out some necessary JS code in controller or customControl folders.

23.png

But can we change the behavior of class without modification of source code? Yes we can!

For instance assume that in \QM_MLTPL_RR_S1\customControl\CodeGroupInput-dbg.js we have to “redefine” onConfirm method. How to do it?

 

/*
 * Copyright (C) 2009-2022 SAP SE or an SAP affiliate company. All rights reserved.
 */
//for Template8
sap.ui.define(["sap/m/Input",
…
    "i2d/qm/inspmltpl/resultsrecords1/util/UpdateSidePanel",
    "i2d/qm/inspmltpl/resultsrecords1/model/formatter"
], function (Input, …, UpdateSidePanel, formatter) {
    "use strict";
    return Input.extend("i2d.qm.inspmltpl.resultsrecords1.customcontrol.CodeGroupInput", {
        onConfirm: function (oEvent) {

 

The 1st step is to import class to our code.

24.png

Then override old behavior using  prototype

 

// When F4 value is selected
CodeGroupInput.prototype.onConfirm = function (oEvent) {
 var aContexts = oEvent.getParameter("selectedContexts");
...
}

 

we can call super method by

 

CodeGroupInput.prototype.onConfirm.apply(this, arguments);

 

& even rewrite it completely if we want.


In next article let’s discus deploying Adaptation project to SAP & loading previous version & creating tile for our “enhancement”.

1 Comment
Labels in this area