Manifest File for Routing for Master Details (SplitApp)

Introduction

Sometime in UI5 it is required to make a Master Detail Application, which looks something like this:

UI5 Manifest for SplitAppThere are two ways in which we can achieve the above layout:

  1. By using Fragments for each Master tab pages (with single controller)
  2. By using Individual View for each Master tabs (with individual controller)

In case, you are planning for a very small App, then go with the first use case, else choose second one.

For the first use case, the navigation among tabs will work as mentioned below:

this.getView().byId("<ID of NavContainer>").to(this.getView().byId("<Page_ID of the tab>"));

In the above statement, we get the required Page ID (this page can have a fragment), and then open that page. All the pages are defined within single view. To ease the coding and visibility of the code, we divide each page into fragments. Still in case of a big project, this is not a recommended way.

For the second use case, we will divide the code into given three steps:

  1. App View Code: The App is defined as SplitApp here.
  2. Manifest Code: The Navigation is divided among Master and Detail using target
  3. Master Section: This section contains a tnt:NavigationList which has the same key as the name of the views

Changes in App View File

When we create a blank UI5 Application, it is create with a blank view and controller. It is important to create a App view on top of these Individual views for pages, so that it can act as a root view for others. SAP recommends to have this file as a root view.
For our requirement, the App will have following code:

App.view.xml

<mvc:View controllerName="testApp.controller.App" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
    <Shell id="shell">
        <App id="app"> 
            <pages>
                <!--Split App to Enable Master Detail Configuration-->
                <SplitApp id="Splitapp" mode="ShowHideMode"></SplitApp>
            </pages>
        </App>
    </Shell>
</mvc:View>

 

App.controller.js

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function (Controller) {
    "use strict";
    return Controller.extend("testApp.controller.App", {
        onInit: function () {
 
        }
    });
});

 

Creation of Master View

Till now, we have created a Split App. Now it is required to create a separate Master Page which will just hold all the navigation tabs as shown below:

Master.view.xml

<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="testApp.controller.Master"
    xmlns:html="http://www.w3.org/1999/xhtml" xmlns:tnt="sap.tnt">
    <Page id="master" title="{i18n>Actions}" backgroundDesign="List" class="sapUiStdPage">
        <!--All Master Pane tabs are maintained here-->
        <tnt:NavigationList id="navigationList" selectedKey="Tab_1" itemSelect="onListItemPress">
            <tnt:NavigationListItem id="MasterData" text="{i18n>Tab_1}" icon="sap-icon://org-chart">
                <tnt:NavigationListItem text="{i18n>Tab_1_1}" key="Tab_1_1"/>
                <tnt:NavigationListItem text="{i18n>Tab_1_2}" key="Tab_1_2"/>
                <tnt:NavigationListItem text="{i18n>Tab_1_3}" id="subItemThree" key="Tab_1_3"/>
            </tnt:NavigationListItem>
            <tnt:NavigationListItem text="{i18n>Tab_2}" icon="sap-icon://leads" key="Tab_2"></tnt:NavigationListItem>
        </tnt:NavigationList>
    </Page>
</mvc:View>

 

Master.controller.js

/**
 * onListItemPress is invoked on click from UI. 
 * Input: Key Maintained in Master View
 * Output: Navigation to the Master Page
 */
onListItemPress: function (oEvent) {
    var that = this;
    var sTimeOutErrorMsg = this.oBundle.getText("TimeOutError");
    var sError;
    var sToPageId = oEvent.getParameter("item").getKey();
    if (sToPageId) {
        try {
            this.oRouter.navTo(sToPageId);
        } catch (err) {
            if (err.statusCode === 401) {
                sError = sTimeOutErrorMsg;
            } else {
                sError = err.error;
            }
            MessageBox.error(sError);
            window.location.href = '../logout';
        }
    }
}

 

Changes in Manifest File

Changes in Manifest File

Here we will do two changes:

  1. Add Routes: It specifies the pattern, name of the route and the target. The pattern specifies what will be visible after the url. Like in below example, pattern will look something like this in URL: test.com/worklist
"routes": [{
    "pattern": "Tab_1",
    "name": "Tab_1",
    "target": [
        "masterTarget",
        "Tab_1"
    ]
}]

 

Sometimes, it is required to pass some values too during navigation, from one page to other. In that case, the routes looks something like below. Here we are passing an ID during navigation. This ID looks something like this in URL: www.test.com/overview/{Id}

In case, passed ID is 10, then the URL will look like this: www.test.com/overview/10

"routes": [{
    "pattern": "Tab_1/{Id}",
    "name": "Tab_1",
    "target": [
        "masterTarget"
                         "Tab_1"
    ]
}]

 

*Note: As you can see, we have added double targets here. The first one keeps the Master View always open and the second one will navigate to a view called Tab_1.

  1. Add Targets: Once we have added routes, each route point to a particular target. This target actually points out the right file for navigation. Here we will use the first route that we discussed above to reach our target view. The viewName mentioned below is actually pointing to the view that will open up, after navigation is performed. For both of the above routes, targets will look something like below, only the name, title and IDs will change.
"targets": {
                        "masterTarget": {
        "viewType": "XML",
        "transition": "slide",
        "controlAggregation": "masterPages",
        "viewId": "idMaster",
        "viewName": "Master",
        "viewLevel": 1,
        "controlId": "Splitapp"
    },
                "Tab_1": {
        "viewType": "XML",
        "transition": "slide",
        "controlAggregation": "detailPages",
        "viewId": "idTab_1",
        "viewName": "Tab_1",
        "viewLevel": 2,
        "controlId": "Splitapp"
    }
}

 

Note: In the above targets, the controlAggregation decides which type of page it is. Also the controlId remains same for all the targets.

Full Manifest Code

{
    "_version": "1.12.0",
    "sap.app": {
        "id": "testApp",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "applicationVersion": {
            "version": "1.0.1"
        },
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "sourceTemplate": {
            "id": "servicecatalog.connectivityComponentForManifest",
            "version": "0.0.0"
        },
        "dataSources": {
            "oDataService": {
                "uri": "<Your Service Name>",
                "type": "OData",
                "settings": {
                    "odataVersion": "2.0",
                    "localUri": "<local Metadata>"
                }
            }
        }
    },
    "sap.ui": {
        "technology": "UI5",
        "icons": {
            "icon": "",
            "favIcon": "",
            "phone": "",
            "phone@2": "",
            "tablet": "",
            "tablet@2": ""
        },
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        }
    },
    "sap.ui5": {
        "flexEnabled": false,
        "dependencies": {
            "minUI5Version": "1.65.6",
            "libs": {
                "sap.ui.layout": {},
                "sap.ui.core": {},
                "sap.m": {}
            }
        },
        "contentDensities": {
            "compact": true,
            "cozy": true
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "testApp.i18n.i18n"
                }
            },
            "@i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "uri": "i18n/i18n.properties"
            },
            "ODataModel": {
                "type": "sap.ui.model.odata.v2.ODataModel",
                "settings": {
                    "defaultOperationMode": "Server",
                    "defaultBindingMode": "TwoWay",
                    "defaultCountMode": "Request",
                    "json": true,
                    "defaultUpdateMethod": "PUT",
                    "useBatch": false
                },
                "dataSource": "oDataService",
                "preload": true
            }
        },
        "resources": {
            "css": [{
                "uri": "css/style.css"
            }]
        },
        "rootView": {
            "viewName": "testApp.view.App",
            "type": "XML",
            "id": ""
        },
        "routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewPath": "testApp.view",
                "controlId": "app",
                "bypassed": {
                    "target": ["NotFound"]
                }
            },
            "routes": [{
                "name": "Tab_1",
                "pattern": "",
                "target": ["masterTarget", "Tab_1"]
            }, {
                "name": "Tab_2",
                "pattern": "Tab_2",
                "target": ["masterTarget", "Tab_2"]
            }],
            "targets": {
                "masterTarget": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "masterPages",
                    "viewId": "idMaster",
                    "viewName": "Master",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Tab_1": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idTab_1",
                    "viewName": "Tab_1",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Tab_2": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idTab_2",
                    "viewName": "Tab_2",
                    "viewLevel": 2,
                    "controlId": "Splitapp"
                }
            }
        }
    },
    "sap.platform.hcp": {
        "uri": "webapp",
        "_version": "1.1.0"
    }
}

 

 

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.