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: 
AlwinPut
Active Participant
The Fiori Elements app below shows a List Report + Object Page with Moving Objects which have a geo location. There are 5 Moving Objects in the list and Moving Object 3 is selected. It's location is near Amsterdam.


When clicking on the spot Plane 3 a popup with the selected Moving Object. The purpose of this is to explain how geo map events must be handled in JavaScript code.


This Fiori Elements app is generated based on ABAP CDS views with annotations. The List Report Flexible Column Layout property is set to true and that's why the List Report (left part) and the Object Page (right part) are both shown side by side.

The Geo Map is placed in a Custom Section. Custom Sections is one of the Extension Points technique of the Fiori Elements Flexible Programming Model. The creation of this geo map extension is explained in the blog post below.

The first part of the blog post is based on OData V4. The last part contains extra information about OData V2 and the reason why you might prefer OData V2.

Table of Content


Object Diagram
Custom Fragment and Event Handler
Object Page - Controller Extension
Section Title Text translations
Flexible Column Layout
Use OData V2
Advice OData V2 or V4?
References

Object Diagram



Highlights

  • The <<Custom Fragment>> is used for the Geo Map control.
    The Geo Map control uses the models of the app which are defined in the manifest.json.


 

  • If you want to catch events of the Geo Map like for example the Spot click

    • Then the <<Event Handler>> is needed.

    • <<Custom Fragment>> has a reference to the <<Event Handler>>.

    • <<Custom Fragment>> fires event to the <<Event Handler>>.




 

  • If you need an initialization event like onAfterRendering events as we need now to set the Map Configuration of the Geo Map.

    • Then <<Controller Extension>> is needed.

    • The manifest.json contains the reference from the Object Page Controller to the <<Controller Extension>>.

    • The <<Extension Controller>> has access to the <<Extension API>>.

    • The <<Extension API>> has access to the <<Custom Fragment>> via the Core Controller.




 

  • If you need to access the model in <<Event Handler>> or <<Extension Controller>>

    • Then the use <<Extension API>> which has access to the <<Model>> via the ObjectPageView.




 

Custom Fragment and Event Handler


Steps



  • Go to the Page Map

    • Push button Configure Page



  • Push button Add Sections

  • Push button Add Custom Section

  • Fill screen "Add Custom Section


    • See at field "View Type" that is not possible to create a View.
      In OData V2 the views are supported, but in OData V4 not anymore.
      In OData V4 there will controller will be a Controller Extension on the Object Page for the initialization events. And we use an Event Handler to handle the events of the controls of the Custom Fragment.

    • See also at field "Generate Event Handler" that the Event Handler will be generated.



  • Push button Add.


The generated files


See in the folder ext that the Fragment XML file and Event Handler JS file are created:



manifest.json


The manifest file is extended. The target, which can be seen as page, is extended with section "Geomap". See the code below. All the values of the "Add Custom Section" screen are added to this section, like template, position and title.
    "sap.ui5": {
...
"routing": {
...
"targets": {
...
"MovingObjectObjectPage": {
"type": "Component",
"id": "MovingObjectObjectPage",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings": {
"editableHeaderContent": false,
"entitySet": "MovingObject",
"content": {
"body": {
"sections": {
"Geomap": {
"template": "zgeomovingobjectlistv4.ext.fragment.Geomap",
"position": {
"placement": "After",
"anchor": "idGeneralInformation"
},
"title": "Geo Map",
"type": "XMLFragment"
}
}
}
}
}
}
}

Highlights


  • "template": "zgeomovingobjectlistv4.ext.fragment.Geomap"
    This is the reference to the Custom Fragment.
    It is not a reference to the Event Handler, because that reference is defined in the Custom Fragment.

  • "position": { "placement": "After", "anchor": "idGeneralInformation" }
    The placement of the Custom Section.

  • "title": "Geo Map"
    Title of the custom section.

  • "type": "XMLFragment"
    The view type is always an XML Fragment.



Custom Fragment XML view


Add the code below to the fragment XML file.
<core:FragmentDefinition 
xmlns:core="sap.ui.core"
xmlns="sap.m"
xmlns:macros="sap.fe.macros">

<mvc:View
id="zView"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:l="sap.ui.layout"
xmlns:vbm="sap.ui.vbm">

<l:VerticalLayout id="verticalLayout" width="100%">

<vbm:GeoMap
id="GeoMapControl"
width="100%"
height="400px"
centerPosition="{GeoLongitude};{GeoLatitude}"
zoomlevel="10"
core:require="{ handler: 'zgeomovingobjectlistv4/ext/fragment/Geomap'}"
>

<vbm:vos>
<vbm:Spots id="GeoMapSpots"
posChangeable="true"
scaleChangeable="false">
<vbm:items>
<vbm:Spot id="Spot"
position="{GeoLongitude};{GeoLatitude};0"
tooltip="{ObjectTypeText} {ObjectId} - {GeoLongitude};{GeoLatitude}"
type="Success"
icon="shipping-status"
text="{ObjectTypeText} {ObjectId} "
contentOffset="0;0"
click="handler.onClickSpot">
</vbm:Spot>
</vbm:items>
</vbm:Spots>

</vbm:vos>

</vbm:GeoMap>
</l:VerticalLayout>

</mvc:View>

</core:FragmentDefinition>

Highlights


  • By default a Custom Fragment is linked to the models of the app.
    These models are defined in the manifest.json in section "models".
    We make use of the default model, which is model "" in the manifest.json.

  • core:require="{ handler: 'zgeomovingobjectlistv4/ext/fragment/Geomap'}"
    ... is the link to the event handler.
    The event handler object Geomap.js is generated also in folder ext/fragment.



Event Handler: Geomap.js


Add this code to the Event Handler for the forward navigation from the List Report to the Object
sap.ui.define([
"sap/m/MessageToast"
],
function(MessageToast) {
'use strict';

//Create event handler object
return {

//Handle event of fragment
onClickSpot: function(oEvent) {

var MovingObject = oEvent.getSource().getBindingContext().getObject();

alert('Selected: ' + MovingObject.ObjectTypeText + ' ' + MovingObject.ObjectId);

}

};

});

Highlights


  • In the Custom Fragment the onClickSpot function is registrered to the Spot click event. When the user clicks on a Geomap Spot the function onClickSpot will be called.

  • oEvent is the click event of the Geomap Spot.

  • Function getSource() gets the Geomap Spot itself.

  • Function getBindingContext gets the Binding Context of Geomap Spot.
    A Binding Context is the selected record in the model.
    The Binding Context contains a path to the selected record like /MovingObject(3).

  • Function getObject() gets the data object of the selected record.


Object Page - Controller Extension



For the Geomap we need to set initially a Map Configuration to specify the map provider. In our case the map provider will be OpenStreetMap. In OData V4 a Controller Extension has to be created to handle the onAfterRendering event.

Steps



  •  Open the Page Map

  • Push button Show Controller Extensions

  • Push button "Add Controller Extension"

  • Fill screen and push Add


manifest.json


The manifest.json contains the reference from the ObjectPageController to the Controller Extension.
{
...
"sap.ui5": {
...
"extends": {
"extensions": {
"sap.ui.controllerExtensions": {
"sap.fe.templates.ObjectPage.ObjectPageController#zgeomovingobjectlistv4::MovingObjectObjectPage": {
"controllerName": "zgeomovingobjectlistv4.ext.controller.ZMovingObjectController"
}
}
}
}

Controller: ZMovingObjectController.controller.js


See in folder ext / controller the Extension Controller file.


Add the code below to the controller file.
			onAfterRendering: function (oObjectPageEvent) {

//Get Extension API
var oObjectPageController = this;
var oExtensionAPI = oObjectPageController.base.getExtensionAPI();

//Get Geo Map Controller. Full id: "zgeomovingobjectlistv4::MovingObjectObjectPage--fe::CustomSubSection::Geomap--GeoMapControl"
var oGeomapController = oExtensionAPI.byId("fe::CustomSubSection::Geomap--GeoMapControl");

//Set Map configuration
var oMapConfig = {
"MapProvider": [{
"name": "OSM",
"type": "",
"description": "",
"tileX": "256",
"tileY": "256",
"maxLOD": "20",
"copyright": "OpenStreetMap",
"Source": [{
"id": "s1",
"url": "https://a.tile.openstreetmap.org/{LOD}/{X}/{Y}.png"
}]
}],
"MapLayerStacks": [{
"name": "DEFAULT",
"MapLayer": [{
"name": "OSMLayter",
"refMapProvider": "OSM",
"opacity": "1.0",
"colBkgnd": "RGB(255,255,255)"
}]
}]
};

oGeomapController.setMapConfiguration(oMapConfig);
oGeomapController.setRefMapLayerStack("DEFAULT");
}


Highlights


  • This Controller Extension object is linked in the manifest.json to the Object Page Controller.

  • The object variable "this" is a link to the Object Page Controller.

  • The Extension API is retrieved from the Object Page Controller.
    It is very import to use the extensionAPI as much as possible for upgrade stability.

  • The function getId() is used from the Extension API to get a reference to the Geo Map Controller. The function getId() retrieves the link via the SAPUI5 Core object.

  • The function setMapConfiguration() sets the Map Configuration of the Geo Map Controller.

  • The function setRefMapLayerStack() sets the Map Layer Stack which is defined in the Map Configuration.


Section Title Text translations


Adjust title in manifest.json
                "MovingObjectObjectPage": {
"options": {
"settings": {
"content": {
"body": {
"sections": {
"Geomap": {
"title": "{i18n>geomapSection}"

For explanation: i18n is the model for texts. See in manifest .json.
    "sap.app": {
"i18n": "i18n/i18n.properties",

"sap.ui5": {
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "zgeomovingobjectlistv4.i18n.i18n"
}
}
"@i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
}

Add geomapSection property to i18n/i18n.properties file
geomapSection=Geo Map

Flexible Column Layout


To show the Object Page in the same window as the List, we have to activate the Flexible Column Layout.

  • Go to the Page Map

  • Switch from "Standard Layout" to "Flexible Column Layout".


Use OData V2


Create Custom View


In Fiori Elements for OData V2 you do not use a Controller Extension as controller, but you create a View with a Controller. The rest is the same.


It creates a Custom View and a Custom View Controller. The code for the Custom View Controller is not exactly the same as the code for the OData V4 Controller Extension.

The View Controller does not have a property base, so you have to use the property this, which is referencing itself. The code for the Custom Controller is:
sap.ui.define(['sap/ui/core/mvc/Controller'], function(Controller) {
'use strict';

return Controller.extend('zgeomovingobjectlisto2.ext.GeomapByBinding', {

onInit: function () {

//Set Map configuration
var oMapConfig = {
"MapProvider": [{
"name": "OSM",
"type": "",
"description": "",
"tileX": "256",
"tileY": "256",
"maxLOD": "20",
"copyright": "OpenStreetMap",
"Source": [{
"id": "s1",
"url": "https://a.tile.openstreetmap.org/{LOD}/{X}/{Y}.png"
}]
}],
"MapLayerStacks": [{
"name": "DEFAULT",
"MapLayer": [{
"name": "OSMLayter",
"refMapProvider": "OSM",
"opacity": "1.0",
"colBkgnd": "RGB(255,255,255)"
}]
}]
};

var oGeoMap = this.getView().byId("GeoMap");
oGeoMap.setMapConfiguration(oMapConfig);
oGeoMap.setRefMapLayerStack("DEFAULT");

}
});
});

Advice OData V2 or V4?


After making this blog post I noticed a difference between List Reports based on OData V2 and List Reports based on OData V4.

List Reports based on OData V2 do not rebuild the Object Page after clicking on a next List Report Line Item. And it stays on the selected section.


See that only the data in the screen is updated, and the object page is not fully reloaded. And the object page stays at selected Section.

List Reports based OData V4 do rebuild the Object Page after clicking on a next List Report Line Item and after rebuilding it scrolls down to the latest selected section. This is what happens on line item click.


See that the Object Page is being fully reloaded.

So List Reports for OData V2 are quicker and do not do unnecessary scrolling.

But, if you also want to add a Custom Tab on the List Report, than you have to choose for OData V4, because that's only possible with OData V4. See SAPUI5 Documentation topic Extension Points for Views in the List Report.

So if you do not need a List Report Custom Tab, then I would choose for OData V2, but if you do need it, then you must choose for OData V4.

 

If you have any comments, improvements or additions, please send them to me or add a comment to this blog post and I will update the blog post.

 

References


2 Comments
Labels in this area