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: 
akshaya_p
Contributor
Hi All,

Fiori elements have proved to be a very powerful tool for enhancing and developing complex , robust  SAP Fiori  applications that give the users flexibility to perform a wide range of operations on the UI. But the challenge comes when we want to enhance them to suit our needs. Following are some practices and tips that helped me in these extensions

  1. Object Page Sections Layout


The object page facet annotations diplay FieldGroups in a column Layout. It adaps to the screen and is of course the default. But sometimes we would want a layout that's more compact and is still responsive. Below is the comparison of the two layouts and how to achieve the latter

Column layout



 

Responsive Layout



 

Steps for Responsive Layout in the Object Page

1.Add an objectpage extension controller ( add any extension in objectpage  to get that controller)

2. The object page is rendered as Sections->Subsections->Blocks. Hence onInit method add the below code. You can always adjust the sizing to suit your needs.
	this.getView().getContent()[0].getSections()[0].getSubSections()[0].getBlocks()[0].getContent()[0].setLayout(new sap.ui.comp.smartform
.Layout({
columnsXL: 3,
columnsL: 3,
columnsM: 3,
labelSpanXL: 2,
labelSpanL: 4,
labelSpanM: 5,
labelSpanS: 6,
gridDataSpan: "XL2 L3 M3 S6",
emptySpanXL: 0,
emptySpanL: 0,
emptySpanM: 0,
emptySpanS: 0
}));

 

2. Adding CSS or customizing columns in the smart table

There are cases when we need to add custom CSS or perform operations on scroll  or any customizations on columns, which say cannot be done through annotations and extensions.

Then we get the Table (here a responsive table) that's rendered within the smart table and add the operations on "UpdateFinished" method. Now ill have access to all the items inside the responsive table and here I'm doing some operation on press of each item
		this.byId("idSmartTable").getTable().attachEvent("updateFinished", function (data) {
var items = this.byId("idSmartTable").getTable().getItems().length;
var tableItems = this.byId("idSmartTable").getTable().getItems();
for (var i = 0; i < items; i++) {
this.byId("idSmartTable").getTable().getItems()[i].setType('Navigation');
this.byId("idSmartTable").getTable().getItems()[i].attachPress(this.onPressCases, this);

}

 

3. Perform Operations on Object Page loaded 

There will be times when we want to get the data from the list page context or do any operation everytime an object page is loaded, then we have a pageloaded method that the objectpage extension API offers

Note: "This" variable is not accessible inside this method. Hence if u want to use "this" you must declare it somewhere outside and use the global reference here.

OnInit of objectpagecontroller add this
this.extensionAPI.attachPageDataLoaded(this.onDetailsLoaded, this);

	onDetailsLoaded: function (event) {

var sPath = event.context.sPath // has the context path

var contextObj = event.context.getObject();//contains the context Object and has all the properties bound in the list report Item

}

 

4.Access controls by IDs

Accessing controls by IDs is a headache in smarttemplates. You ahve to either inspect and take a loooong ID from the console or any UIs add-on of chrome. This is painstaking and the code also looks jammed with such a loong ID( we never know the ID naming conventions might change too).

use this.getView().byId() that concatenated your custom ID with the View instance
this.getView().byId("id::Table")

You can access this createdId through this.getView().byId(yourcreatedIdAbove).

A neater approach!

 

5. Concatenate Strings in Overview Page Chart Cards

The annotation helper function odata.concat comes in handy when you want to display some customized text on chart cards(chart cards are not very customisable)
	<Record Type="UI.DataField">
<PropertyValue Property="Value">
<Apply Function="odata.concat">
<String>Current Tier</String>
<String></String>
<String>:</String>
<String></String>
<Path>tierlevel</Path>
</Apply>
</PropertyValue>
<PropertyValue Property="Label" String="{@i18n&gt;CURRENT_TIER}"/>
</Record>

 

6. Default Parameters in search of SmartFilterBar when Navigating from launchpad

When we have dynamic tiles in launchpad and we want a certain searchfield to be filled when navigated from launchpad, the attachInitialized method of filterbar does this (Note: its NOT initialise)

You can then access the components startup parameters and FireSearch if need be.
	filterBar.attachInitialized(this.onInitSmartFilter, this);

 

7.Clear Column filters in Smarttable

Clear all values from p13nDialog(column filter) in smart Table
smartTable.applyVariant({});

 

8.Change Default date format in launchpad for OVP cards.

OVP does not allow you to change default date format. Use this code to achieve date format as you desire

 
	sap.ui.getCore().getConfiguration().getFormatSettings().setDatePattern("medium","MMM d,yyyy");

 

9.Removing Data loss popup

In some cases of non-draft apps(where you haven't implemented SAPs draft functionality) we still get the data loss popup. This occurs when the model has pending changes.

To prevent it from coming up, check if the model has pending changes and reset the changes

 

Note:




var currListItemPath = currentListItem.getBindingContextPath();           that.getView().getModel().resetChanges([currListItemPath]);


if we pass path to reset changes, it will only reset that item with no odata call




 
if(oModel.hasPendingChanges())

{

oModel.resetChanges();

}

 

10.Remove context filters on Navigation

In OVP cards when we do a custom Navigation,we sometimes do not want the intent to be passed(say if it redirects to  a dynamic external URL). But if it is semantic bnased Navigation even if we give "Requires Context" = false , it still passes the context by default. To prevent this from happening, we can make the context parameters empty and make "ignoreEmptyString" true in the customParams method
In Manifest.json inside card settings

"customParams": "getParameters"

In Custom Controller

getParameters: function (oNavigateParams, oSelectionVariantParams) {

// to get the select option property names, make use of this to check what values are available to modify
var navParams = Object.keys(oNavigateParams);
var aCustomSelectionVariant = [];

/// logic to remove Filter1
/// assigning empty values to Filter1 and Filter2, with ignoreEmptyString as true, this will be removed from the Selection Variant

var filter1= {
path: "filter1",
operator: "EQ",
value1: oNavigateParams['FIlter1'],
value2: null,
sign: "I"
};



/// logic to remove Filter1

aCustomSelectionVariant.push(filter1);

return {
selectionVariant: aCustomSelectionVariant,
ignoreEmptyString: true
};
},


 

11.Access the controls inside valuehelp dialog

Its great that smart templates give a well organised f4 help dialog box. But tehre are some scenarios where we need to access controls inside the value helps dialog box(say to add extra smartfiletrbar buttons inside the dialog). In that case set a small delay and get the dependents of the valuehelp control.With that you can access all it children!

 
smartfb.getControlByKey("control1").attachValueHelpRequest(this.dialogOpened, this);

dislogOpened:function(event)
{

var control = event.getSource();

var t = this;
setTimeout(function () {
control.getDependents()[0].setBasicSearchText('');

}, 100);

}

 

12.Set filter parameters when navigating from OVP to a normal sapui5 app.

Thre are scenarios when you will be navigating from a smart template app to a normal sapui5 app. In this case the filters will not be carried over from OVP page like how it happens in list report page.

We have to manually set the filter which becomes very tedious. This is when Navigation handler comes in handy. write his code in initialized method of smartfilterbar

 
var oNavigationHandler = new sap.ui.generic.app.navigation.service.NavigationHandler(this);
var oParseNavigationPromise = oNavigationHandler.parseNavigation();
oParseNavigationPromise.done(function (oAppData, oStartupParameters, sNavType) {
oSmartFilter.setDataSuiteFormat(oAppData.selectionVariant, true);
}.bind(this));
}
oSmartFilter.fireSearch();

And lo! all yur filters are set just like in list report!

 

13.Get keys of the context in Object Page
Say you have name,DOB,COmpany as keys of the current entity set in the object page
you can get them as key value pairs

this.extensionAPI.getNavigationController().getCurrentKeys()

will give you an array. It will contain a string like "name='abc',DOB='12/03/91',COmpany='def'"

 

14.Removing Scale Factor /Rounding off in OVP card header/line items


Try to change config settings of the app



sap.ui.getCore().getConfiguration().setFormatLocale("standard");

15. Let the list report app know which card are you coming from


When you want to navigate to a particular section in the object page based on the card from which your are come from in dashboard you can add a parameters to the shellHash.


Note: The position of this parameter varies if its a standard or custom card.In a standard card we should ensure it doesn't mix up with the context parameters and messes up the URL.


Check the difference here in the 'from' parameter.


Standard Card: "SemanticObject-action&/someurlparameters?from='card1'


Custom card:"SemanticObject-action?from='card2'&/someurlparameters


16.Navigate to another app(that has redirection to another system configured in lpd_cust) in new tab from an OVP standard list card


The newer versions of sapui5 does not navigate in new tab from a list card if its navigation with datafieldforntentbasednavigation. to tweak this, use datafieldwithurl in docustomnavigation method , create hash using hrefforexternal and in the url concatenate "/sap/bc/ui2/flp"+hash and Lo it opens in new tab


I'll update this Blog as and when I see and do new things in Fiori elements. Hope you find this Blog useful!

 

17. Custom control in advanced search 

The flexibility to add custom control in a smartfilterbar is not the same as adding a custom control in advanced search(sometimes we want the same control in both places)

For this, first we must undnerstand the structure of advanced search in smartfilterbar value help

The advanced search is split into field groups and each field group displays in a column with a title.

Adding a custom control is possible through addfiltergroupfield(which emans it can be added onloy at the end and nowhere in between as inserfiltergroupitem is deprecated(quite unfortunately :().

In the valuehelprequest method of the f4 in smartfielter bar write this code
	filterBar.addFilterGroupItem(new sap.ui.comp.filterbar.FilterGroupItem({
groupName: "grp1",
label: "Custom label",
partOfCurrentVariant: true,
visibleInFilterBar: true,
name: "custLbl",
control: new sap.m.MenuButton({
menu: menu
})
}));

 

and lo! a new menu button is added at the end of group1 in advanced search . You can then access this control through
event.getSource()._getFilterGroupItemByGroupName('custLbl').getControl()

 

18. Making the correct 'this' instance available inside objectpageloaded method

We have 'attachPageLoaded' method in extensionAPI to add funstions of all extended controls in smart templates.

This method has the context object of that page and 'this' points to the event object here. Hence to get the actual controller object 'this' we can use javascript bind method, to pass the desired 'this' when instantiating the method

 

var mempageloaded = this._memPageDataLoaded.bind(this); this.extensionAPI.attachPageDataLoaded(mempageloaded);



So inside

_memPageDataLoaded function 'this' will point to the controller object and we can easily access all methods inside the controller as desired.


19.Visual Filters not rendering in ALP


If you have brand in both the compact and visual filter, map the brand's valuehelpset to the compact filter in collection path(properties-brand common.valuelist) and the main entity set in visual filter(properties -brand common.valuelist with a qualifier,presentation variaint pointing to the chart and no parameters).


Both will sync automatically



20.Download custom column also from smart table in export to excel


give the name of a backend property pertaining to the entity(connected to smart table) as columnKey to the custom column. It Will be downloaded automatically


21.Smart fields in custom fragments


There are scenarios when you need s smart field in your custom fragment,. like say a value help similar to you smartfilterbar


SMart field come sin handy at such places. After going through a lot of documentation and blog i still couldnt get the smart field editable. Why?


Things to do before the UI design

1. Make the entity set updateable

2. Make the property updateable

3. Write annotations for valuehelp(valuelist) the same way as smartfielterbar


Then you can use the smart field inside a simple form or a smart form( the forms should have updateable true as well)




<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form"
xmlns:smartTable="sap.ui.comp.smarttable" xmlns:sf="sap.ui.comp.smartfield" xmlns:form="sap.ui.comp.smartform">
<Dialog id="onlineavailabilityid2" title="{@i18n>List_to_Search}" resizable="true" contentWidth="40%" afterClose="dialogAfterclose">
<content>
<!--BTCCECSC-234-->
<f:SimpleForm id="form" editable="true">
<Label labelFor="idStore" text="Select Store" design="Bold"></Label>
<sf:SmartField value="{property1}" id="idStore" mandatory="false" entitySet="entityset">
<sf:layoutData>
<l:GridData spanL="1" spanM="1" spanS="1"/>
</sf:layoutData>
<sf:configuration>
<sf:Configuration preventInitialDataFetchInValueHelpDialog="true"/>
</sf:configuration>
</sf:SmartField>
</f:SimpleForm>


SmartForm

<core:FragmentDefinition xmlns:commons="sap.ui.commons" xmlns:core="sap.ui.core" xmlns:form="sap.ui.layout.form" xmlns:l="sap.ui.layout"
xmlns:sfi="sap.ui.comp.smartfield" xmlns:sfo="sap.ui.comp.smartform" xmlns:table="sap.ui.table"
xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1" xmlns:uxap="sap.uxap" xmlns="sap.m"
xmlns:f="sap.ui.layout.form" xmlns:smartForm="sap.ui.comp.smartform" xmlns:smartField="sap.ui.comp.smartfield">

<smartForm:SmartForm id="smartFormGeneral" editable="true">
<smartForm:Group id="Generalinfoid">
<smartForm:GroupElement label="{@i18n>text}">

<sf:SmartField value="{property1}" id="idStore" mandatory="false" entitySet="entitysetname">
<sf:layoutData>
<l:GridData spanL="1" spanM="1" spanS="1"/>
</sf:layoutData>
<sf:configuration>
<sf:Configuration preventInitialDataFetchInValueHelpDialog="true"/>
</sf:configuration>
</sf:SmartField>
</smartForm:GroupElement>



22.Replacing standard UI texts

When you use the standard update or create , the CRUD operations are handled by the framework and you get messages that are very generic to change those messages yo'll have to find the standard i18n files and then make changes tehre




<WEBIDE URL>

/resources/sap/suite/ui/generic/template/lib/i18n/i18n.properties


<WEBIDE_URL>

/resources/sap/suite/ui/generic/template/ListReport/i18n/i18n.properties




<WEBIDE_URL>/resources/sap/suite/ui/generic/template/OnjectPage/i18n/i18n.properties

 

23.Influencing the order of grouping in analytical table

display the columns in the same order as u want in the lineitem annotation, if you dont want the column to be visible after grouping you can get the table and set ifgrouped property as below. also for grouping set the requestatlestfields and if sort is needed, sortby property in the presentation variant annotation
var table=this.getView().byId("table") // this is how you access the table in ALP
var columns=table.getColumns();
for(var key in columns)
{
this.getView().byId("table").getColumns()[key].showIfGrouped(false);
}

 

24.Displaying only the text in smartfilterbar F4/ dropdown

In CDS give the text annotation for the field mapped in the smartfilterbar. if you have , say , employee id map the employeedesc field as sap:text( do this in the valuehelp set for the annottaion to take effect in the smartfilterbar)

If sap-semantics=fixed-values cannot be imposed at CDS level,  give valuelistWithfixed values annotation in annotation file or get the filterbar controlconfiguration and set the desired field
	var oControlConfigs = this.getView().byId("SmartFilterBar").getControlConfiguration();
for (var key in oControlConfigs) {
if (oControlConfigs[key].getKey().match(/employee/gi)) {
oControlConfigs[key].setControlType(sap.ui.comp.smartfilterbar.ControlType.dropDownList);
}
}

 

as dropdownlist

25. How to refresh a fragment?

fragmentname.rerender();

 

26. Generate Dynamic controls but not from the Controller-Nested List?

There are scenarios where you will want to create dynamic controls but you wnat it like a binding fro m the view. How?

Factory functions comes to the rescue. Factory functions help to create dynamic controls when you cannot do it from the controller( because u cannot access the element since ot is a list of lists)

 
	<List  noDataText="{@i18n>noFields}"
items="{path: 'disputes>entityset',factory:'.createContent',templateShareable: false}"></List>

Create fragments for the two different types of templates that you want to determine at runtime

say- one fragment for edit ( different fields-input,checkbox, select etc)
one fragment for display ( all text fields)


Controller code
createContent: function(sId, oContext) {
var oUIControl;

// Decide based on the data which dependent to clone
if (oContext.getProperty("UnitsInStock") === 0 && oContext.getProperty("Discontinued")) {
// The item is discontinued, so use a StandardListItem
oUIControl = this.byId("productSimple").clone(sId);
} else {
// The item is available, so we will create an ObjectListItem
oUIControl = this.byId("productExtended").clone(sId);

// The item is temporarily out of stock, so we will add a status
if (oContext.getProperty("UnitsInStock") < 1) {
oUIControl.addAttribute(new ObjectAttribute({
text : {
path: "i18n>outOfStock"
}
}));
}
}

return oUIControl;
}

 

27.Generate Valuehelp Similar to smart fields

Scenario where there will be a need to create an F4 similar to smartfield

  1. Create a fragment for the F4 dialog


  2. <core:FragmentDefinition
    xmlns="sap.ui.comp.valuehelpdialog"
    xmlns:core="sap.ui.core">
    <ValueHelpDialog
    title="a value"
    ok=".onValueHelpOkPress"
    cancel=".onValueHelpCancelPress"
    afterClose=".onValueHelpAfterClose"
    key="Value"
    descriptionKey="Description"
    supportMultiselect="false"
    tokenDisplayBehaviour="descriptionOnly"
    >
    </ValueHelpDialog>
    </core:FragmentDefinition>

    	onValueHelpRequest: function (event) {
    this.vhpSource = event.getSource();
    var vhpSet = event.getSource().getBinding("suggestionItems").sPath;
    this._oValueHelpDialog = new sap.ui.xmlfragment("namespace.fragment.ValueHelpDialog", this);
    var filters = event.getSource().getBinding("suggestionItems").aApplicationFilters;
    this.getView().addDependent(this._oValueHelpDialog);
    this._oValueHelpDialog.getTableAsync().then(function (oTable) {
    oTable.bindAggregation("rows", {
    path: vhpSet,
    filters: filters
    });

    var oTemplate = new sap.ui.table.Column({
    label: new sap.m.Label({
    text: "Description"
    }),
    template: new sap.m.Text({
    text: "{Description}"
    })
    });
    if (oTable.bindColumns) {
    oTable.addColumn(oTemplate);

    }
    this._oValueHelpDialog.update();
    }.bind(this));
    this._oValueHelpDialog.open();

    },

    28. Getting 'this' instance in formatter

    Sometimes we want the current instance instead of the controller instance, this is how we do it


add a new formatter file , say format.js.In your view/fragment inclusde i within the control(this is possible after version 1.68)
<core:Item key="{Code}" core:require="{ format: 'znamespace/ext/models/format' }" enabled="{parts:[{path:'Enabled'},{path:'enabled2'}],formatter: 'znamespace.ext.models.format.formatEnabled'}"/>

and in format.js
sap.ui.define(function () {
return {
formatEnabled: function (enabled, enabled2) {
var flag = this.getParent().getBindingContext().getObject().someflag; //this references the current control
if (flag) {
return enabled2;
} else {
return enabled;
}

}
};
}, /*expose globally*/ true);

 

29.Adding custom data thro app:

 

add this in namespace
 xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"

add this in your control

<Select app:somedata="{datafrombackend}">

access in controller

this.getView().byId("select").data().somedata


30. Get binding context of custom facets
in Smart templates when we have custom fragments, they are automatically bound to the view and the binding context is not exposed. Say we wanrt to refresh only that aprticular facet we could sue the bind element for it


	
var sPath=this.getView().getBindingContext().sPath;
this.getView().byId("customfacetid").bindElement(sPath, {
expand: "navigationproperty"
});

 

 

31. Change app language by sending language as URL Params through code

Remember to set annotations URI if your model is for a smart template (getparameters->annotationsuri)


var custSrvUrl=this.getOwnerComponent().getModel().sServiceUrl;

var oModel = new sap.ui.model.odata.v2.ODataModel({

serviceUrl:custSrvUrl,

serviceUrlParams: {

"sap-language": "ES",

},

metadataUrlParams: {

"sap-language":"ES"

}


 32.Using text annotation for a property. Works only for multiselect fields( for single select only the code displays)

   <Annotations Target="Metadata.VHPName/City">
<Annotation Term="Common.Text" Path="CityName">
<Annotation Term="UI.TextArrangement" EnumMember="UI.TextArrangementType/TextOnly"/>
</Annotation>

 

33.Declaring a property as measure or dimentsion in UI annotations
    <Annotations Target="Metadata.UserDetails/StoreId">
<Annotation Term="Analytics.Dimension" Bool="true"/>

34 . Points to remember when creating a pie/donut chart

Ceratin chart properties are mandatory to be declared in manifest.json for these two types of chart to be rendered
35. Set filter data to multitoken field in smartfilterbar


var filterdata = this.getView().byId("listReportFilter").getFilterData();
filterdata["Status"] = { // here your value help field
"items": [{
key: somevalue// Pass the key here
}]
};
this.getView().byId("listReportFilter").setFilterData(filterdata);

You can also directly set filterdata by setting the JSON


36.Read data from a smarttable
Since the smarttable directly reads data from odata it is usually not possibly to read the data bound to the table unless we access the inner table.In this case "events parameter comes to the rescue

You can add change,datarequested,datareceived,attachdatastatechange events to the beforerebindtable/beforerebindtableextension(if its a list report) method

onBeforeRebindTableExtension: function (event) {

event.getParameters()["bindingParams"].events = {
"dataRequested":function(er)
{

},
"dataReceived": function (ec) {

ec.getParameter("data") //this will give the table resultset
}

37.CHange Nav from Responsive Table in object page
First make the responsive table in object page clikable. for this add an empty pages aggregation in the manifest and add cross navigation outbounds


under sap.app add this
"crossNavigation": {
"inbounds": {},
"outbounds": {
"WebUi": {
"semanticObject": "someobj",
"action": "display"
},
"to_Disputes4mOrderList": {
"semanticObject": "someobj1",
"action": "action"
}
}
}



add under object page

"ObjectPage|navprop": {
"navigationProperty": "navprop",
"entitySet": "navset",
"component": {
"name": "sap.suite.ui.generic.template.ObjectPage"
},
"pages": {

}
}

 

After this follow this doc

https://sapui5.hana.ondemand.com/#/topic/b20dc7a3d9ca41bebdb86fc3ae3295bf.html

37. Refresh smart table

this.extensionAPI.refresh(tableid);

38. Decouple read calls

if you are using model.read, use groupId

if you are using bindElement use {parameters:{

groupId:'someid"}

39. In standard templates sometimes you might have to override standard actions to have your own custom actions. To do this you need to craete a custom action button, write logic to hide the standard button and attach logic for the custom button

Use refreshAncestors to refresh list report from Object page.

Use the below code for custom back nav from object page
	var oCrossAppNavigator = sap.ushell.Container.getService("CrossApplicationNavigation");
var oUrlParsing = sap.ushell.Container.getService("URLParsing");
var semanticObject = oUrlParsing.splitHash(oUrlParsing.getHash(window.location.href));
if (semanticObject.appSpecificRoute) {
var listHash = semanticObject.shellPart;
this.extensionAPI.refreshAncestors(1);
new sap.ui.core.routing.HashChanger().setHash(listHash);
} else {
oCrossAppNavigator.toExternal({
target: {
shellHash: "#"
}
});
}

 

ShellHash # Navigates back to launchpad

 

 

40. Extening Smartform in a collection Facet

A collection facet is rendered as a subsection and henc doesnt show up in facet extension. To overcome this, we can use smartform extension, where we can add the ID of the reference Facet(that is referenced inside collection facet) and a field gets added up at the end of the form

 
"SmartFormExtension|entityset|idofreferencefacet":
{
"type": "XML",
"className": "sap.ui.core.Fragment",
"fragmentName": "<fragmentpath>"
}

 

41. Use protected methods from SAPUI5 API
	oEvent.getSource().getInnerControls()[0].onBeforeRenderingDropdown = function(e) {

if (sap.m.ComboBox.prototype.onBeforeRenderingDropdown) {
sap.m.ComboBox.prototype.onBeforeRenderingDropdown.apply(this, arguments);
}
// Your code...
};

 

42. Prevent browser mouseover events triggering on scroll

use a delay function in this case to prevent mouse over occuring during scroll.

Inside this function definition, settimeout on mouseover and clear it on mouseout
	var delay = function (elem, callback) {
var timeout = null;
elem.attachBrowserEvent("mouseover", function () {

timeout = setTimeout(callback, 1000);

});

elem.attachBrowserEvent("mouseout", function () {
// Clear any timers set to timeout
clearTimeout(timeout);
});
};
//call the above function to open popover
delay(control, function () {
//define what to happen during mouseover. here it opens a popover
popover.openBy(control);
});

 

43. use serviceurlparams( attaches itself to every request in model) in manifest.json.You can  add to measure sap-statistics  that attaches itself with every batch request

Use it inside model for manifest.json

"": {
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Server",
"defaultBindingMode": "TwoWay",
"defaultCountMode": "Inline",
"serviceUrlParams":{
"sap-statistics":true
}
},

"dataSource": "mainService",
"preload": true
},

 

44. Navigate to an app in create mode
var oNavControl = this.extensionAPI.getNavigationController();



oNavControl.navigateExternal("outboundsnameinmanifest", {
param1: value,
preferredMode: "create"

});

"crossNavigation": {
"inbounds": {},
"outbounds": {
"outboundsnameinmanifest": {
"semanticObject": "zappname",
"action": "display"
}



in Destination app
"sap.ui.generic.app": {
"_version": "1.3.0",
"settings": {
"inboundParameters": {
"param1": {
"useForCreate": true
},

45. Clientside mandatory check

If you want to conditionally mandate smartfields set nullable false from backend. use setmandatory from frontend and for mandatory check use property clientsidemandatorycheck

 

46. Bind elements

for datarequested and datareceived to trigger put path also inside brackets like bindelement({path:"/set"});

 

46.Navigate to app in new tab

in crossapplication navigation add this in params
"sap-ushell-navmode":"explace"

 

47. Calling 3rd party library  in SAPUI5

 
var testLibs = new Promise(function (resolve, reject) {                    sap.ui.require(["sap/ui/thirdparty/require"], function () {                       
requirejs.config({
paths: {
"libs": ["//cdn-stage.libs.com"]
}
});
resolve();
});
});
testLibs.then(require(["libs"], function (libs) {
that.somefunction();
window.some pi.renderPrivateMode({
containerId: "abcd-scrollCont",
locale: "en-US",
siteId: "fgdgdfgfdgdfg",
identifier: "435gfdgdfgdfg",
contact: "test@test.com"
});
}));

sapui5 - External JS lib included by includeScript function is not accessible - Stack Overflow

 

48. Refer to local resources like images in controller

 
   sap.ui.loader.config( {
baseUrl: "../"
} );

var path = sap.ui.require.toUrl( "images/someimage.png" );

 

49.Get context in Replace Header Facet

When you replace header facet you cannot get the context in the specific header facet controller. To get it , Just bind any property in the headerfacetview, use a formatter and You can get the context in the formatter. If you want to make any read calls for specific property you can use the select in URL Parameters
model.read( path,
{
urlParameters: {
"$select": "someprop",
},





formatterfunction: function ( propertypassedfromview) {
var t = this;

if ( propertypassedfromview) {
var context = this.getView().getBindingContext().getObject();
var model= this.getOwnerComponent().getModel( "somemodel" );

 

50.Get local resources inside a project using namespace
var path = sap.ui.require.toUrl( "NameSpace/ext/fragment/somefolder" ) + "/products.json" 

 

51.WriteToDom with Condition for Srikethrough font

write to dom accepts string and if you want your condition in expressionbinding to be converted to string, use this code


<ObjectStatus class="sapUiTinyMarginEnd" text="{somemodel>BasePrice}{somemodel>Currency}" >
<customData>
<core:CustomData key="someproperty-available" value="{=String(${somemodel>someproperty} ==='0.00')}" writeToDom="true"/>
</customData>
</ObjectStatus>


in CSS FIle
div[data-red-price-available="true"] span {
text-decoration: line-through;
}


52. Convert smart template LROP to Flexible column Layout

Pre-requisites: SAPUI5 1.48
"sap.ui.generic.app": {
"_version": "1.3.0",
"settings": {

"flexibleColumnLayout": {
"defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
"defaultThreeColumnLayoutType": "ThreeColumnsEndExpanded"
}
},

Options for 2 column layout – for Master/Detail

  • TwoColumnsBeginExpanded – make the 1st column (master list) wider

  • TwoColumnsMidExpanded – make the 2nd column (detail) wider


Options for 3 column layout – for Master/Master/Detail

  • ThreeColumnsBeginExpanded – make the 1st column wider

  • TheeColumnsMidExpanded ­– make the 2nd column wider

  • ThreeColumnsEndExpanded – make the 3rd column wider


For more details -https://sapui5.hana.ondemand.com/#/topic/e762257125b34513b0859faa1610b09e


53.Content Federation in SAP BTP

Building a central Launchpad using SAP Launchpad Service – Integrating with Remote Content Providers...

Configure Destinations | SAP Help Portal

54. Custom Filter with multiple values( multinput)

When you add a custom filter with multiple inputs Fiori elements getCustomAppStateDataExtension and restoreCustomAppStateData extension doesn't understand   when you save Controls(say an array of sap.m.Tokens) in oCustomData. Instead make it granular and save as simple texts . add the tokens in restoreCustomAppStateDataExtension Method
  getCustomAppStateDataExtension: function ( oCustomData ) {
//the content of the custom field will be stored in the app state, so that it can be restored later, for example after a back navigation.
//The developer has to ensure that the content of the field is stored in the object that is passed to this method.
var oCustomField = this.getView().byId( "somemultiinput" );
oCustomData.artDesc = [];
if ( oCustomField ) {
if ( oCustomField.getTokens() && oCustomField.getTokens().length > 0 ) {
oCustomField.getTokens().forEach( function ( oItem ) {
oCustomData.artDesc.push( {
text: oItem.getText(),
key: oItem.getKey()
} );
} );
}
}

return oCustomData;
},
restoreCustomAppStateDataExtension: function ( oCustomData ) {
//in order to restore the content of the custom field in the filter bar, for example after a back navigation,
//an object with the content is handed over to this method. Now the developer has to ensure that the content of the custom filter is set to the control
if ( oCustomData ) {
if ( oCustomData.artDesc ) {
var oInput = this.getView().byId( "somemultiinput" );
if ( oCustomData.artDesc && oCustomData.artDesc.length > 0 ) {
oInput.removeAllTokens();
oCustomData.artDesc.forEach( function ( oItem ) {
oInput.addToken( new sap.m.Token( {
text: oItem.text,
key: oItem.key
} ) );
} );
}
}
}
},

55. Add Group Id to Split Batches for better performance in xmlView during binding
<f:GridList id="gridList" headerText="{i18n>Products}" items="{ path: '/someset' , suspended: true, parameters: {count: true,groupId:'groupIdsomething'}}" >

 

56. Access Back Button from Object Page 
  this.getOwnerComponent().getService( "ShellUIService" ).then( function ( oShellService ) {
oShellService.setBackNavigation( function () { that.handleCancel(); } );
} );


handleCancel:function(event)
{
//this method will be triggered on pressing back
}

 

57. Add Labels to Chart  and also Stable Colors to Dimensions in OVP

 
"chartSettings": {
"showDataLabel": true,
"enableStableColors": true,
"dimensionSettings": {
"CostElement": { // Dimension Name
"400020": { // Dimension Value
"color":"red",
"legendIndex":0
},
"421000": {
"color":"sapUiChartPaletteSemanticNeutral",
"legendIndex":1
},
"417900": {
"color":"blue",
"legendIndex":2
}
},
“Customer”: {
"C000013": {
"color": "red",
"legendIndex": 0
},
"C000085": {
"color": "blue",
"legendIndex": 0
},
},
"default" : {
"color": "green"
}
}
}
4 Comments
Labels in this area