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!
Showing results for 
Search instead for 
Did you mean: 

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.


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'F3365')

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





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.



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



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


With GET request from the Payload tab


The URL will look like


Let’s try to analyze it the result



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


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


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)


Yes it is CDS reference based SEGW project.


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


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?


  • 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


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 ...


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


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



In NPM scripts just launch start-editor


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


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


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)


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


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



<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
    <Button id="custBtWriteDiff" text="Overwrite difference"


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



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


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" />


& new cell


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


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

Why? Because they statically requested in the view itself.


Let’s add new field via Controller extension

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


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

And we need to change its property requestAtLeastFields


Most of the code can be written without extra JS knowledge. Just find control in UI5 Inspector & find specific event in


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' &&


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




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.


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
], 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.


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