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: 
In standard Fiori apps using Fiori elements the Share feature is available. This feature is also enabled by default if we use the List report Application template provided in Webide. It has two options (when there is no Jam integration) ‘Send Email’ and ‘Save as Tile’.

In this blog I will share my experience how we implemented it for a custom UI5 Application which uses XML views and Java Script controllers.

Getting it on user interface was the easy part. We added a button on the initial View which on press opens up a fragment with 2 options. We used a normal button sap.m.Button for 'Send Email' and AddBookmarkButton control from sap.ushell.ui.footerbar for 'Save as Tile' option.
<OverflowToolbar id="tool">
<Button press="onPressShare" icon="sap-icon://action"/>

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:foot="sap.ushell.ui.footerbar">
<Popover showHeader="false" placement="Bottom" >
<VBox class="sapMPopoverCont">
<Button text="Send Email" press="onPress" iconFirst="true" icon="sap-icon://email"/>
<foot:AddBookmarkButton id="book" text="Save as Tile" title = "Maintenance Notification" showGroupSelection = "true"/>

onPress: function(oEvent) {
sap.m.URLHelper.triggerEmail("", "Link to Maintenance Notification", window.location.href);


But for the functionality to work correctly we had to somehow persist the current app state so that when we click on the saved tile or the email link we see the same context.

How to do it ?

  1. Use Navigation Handler to store the inner app state. Our Application had a Smart Filter and a Smart table on the first view so that users can search for appropriate record/s. As soon as a filter criterion is entered and we search for entries we save the app state.
    onSearch: function(oEvent) {

    var oTable = that.oView.byId("smartTable");
    var oFilt = that.oView.byId("smartFilterBar");

    var mInnerAppData = {
    selectionVariant: oFilt.getDataSuiteFormat(),
    tableVariantId: oTable.getCurrentVariantId()



Here we have selection variant which captures the filter which are set on screen and we save it in Inner App data.

On calling storeInnerAppState we will notice the URL will automatically change and a parameter will be added similar to this –


Note : We will have to define the navigation handler in the controller to use it. 

  1. Add a new Route in manifest file to accommodate handing of URLs with parameter “sap-iapp-state” –
    "routes": [
    "pattern": "",
    "name": "notificationList",
    "target": "notificationList"
    "pattern": ":?sap-iapp-state:",
    "name": "notifListQuery",
    "target": "notificationList"
    "targets": {
    "notificationList": {
    "viewPath": "XXXXX.view",
    "viewName": "NotificationList",
    "viewLevel": 1

   If this is not done we will get an error because the first view has no pattern attached to it -

  1. Add a new data source in manifest and point it to standard Odata service INTEROP where the internal app data is stored –


  1. Add a model with any name, (we used the name GlobalContainers) so that we can make an Odata call to fetch the stored context. 


  1. Finally in the init method of the initial view we incorporate logic to read the app state id and set the saved app data before the first view is loaded. for doing this we parse the app state id from the URL and pass it to the global oData service to retrieve the saved app data. Then we set the appropriate view elements.
    onInit: function() {

    var controller = this;
    this.oNavigationHandler = new NavigationHandler(this);
    that = this;
    var oView = this.getView();
    var appStateKey = "";
    var url = window.location.href;
    var i ='sap-iapp-state');

    if (i > 0) {
    i = i + 15;
    appStateKey = url.substring(i);

    if (appStateKey) {
    var url1 = "/GlobalContainers('" + appStateKey + "')";
    var oModel = this.getOwnerComponent().getModel('GlobalContainers');
    var that1 = this;
    var functionSucess = function(oData, controller) {
    var oFilt = that1.getView().byId("smartFilterBar");
    var obj = JSON.parse(oData.value);
    oFilt.setDataSuiteFormat(JSON.stringify(obj.selectionVariant), true);

    var functionError = function(oError) {
    var test = oError;
    var params = {
    success: function(oData, controller) {
    functionSucess(oData, controller);
    error: function(oError) {
    };, params);


Regards, Saurabh
Labels in this area