Master Detail with multiple views and multiple controllers for detail in SAP UI5

by | Dec 26, 2022 | SAP, UI5, UI5 Programs

Preface – This post is part of the UI5 Programs series.

In this article, we will discuss Master Detail with multiple views and multiple controllers for detail in SAP UI5. Visit this page, in case you are looking for Master Detail with multiple fragments for detail and a single controller.

Master Detail with multiple views and multiple controllers for detail in SAP UI5

App.view.xml

The UI5 App name in our use case is “admin”.

<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
    controllerName="admin.admin.controller.App" xmlns:html="http://www.w3.org/1999/xhtml">
    <Shell id="shell">
        <App id="app">
            <pages>
                <!--Split App to Enable Master Detail Configuration-->
                <SplitApp id="Splitapp" mode="HideMode"></SplitApp> 
               // delete mode if you wan't to always show the Master section
            </pages>
        </App>
    </Shell>
</mvc:View>

App.controller.js

Nothing is to be written App.Controller.js file

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

Manifest.json

1. Change the rootView to App

"rootView": {
            "viewName": "admin.admin.view.App",
            "type": "XML",
            "async": true,
            "id": "app"
        },

2. Update the Routing configuration

"routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "async": true,
                "viewPath": "admin.admin.view",
                "controlId": "app",
                "clearControlAggregation": false
            },
            "routes": [{
                "name": "Login",
                "pattern": "",
                "target": [
                    "masterTarget",
                    "Login"
                ]
            }, {
                "name": "Dashboard",
                "pattern": "Dashboard",
                "target": [
                    "masterTarget",
                    "Dashboard"
                ]
            }, {
                "name": "Appointments",
                "pattern": "Appointments",
                "target": [
                    "masterTarget",
                    "Appointments"
                ]
            }, {
                "name": "Doctors",
                "pattern": "Doctors",
                "target": [
                    "masterTarget",
                    "Doctors"
                ]
            }, {
                "name": "Patient",
                "pattern": "Patient",
                "target": [
                    "masterTarget",
                    "Patient"
                ]
            }, {
                "name": "Subscription",
                "pattern": "Subscription",
                "target": [
                    "masterTarget",
                    "Subscription"
                ]
            }, {
                "name": "Symptoms",
                "pattern": "Symptoms",
                "target": [
                    "masterTarget",
                    "Symptoms"
                ]
            }, {
                "name": "Specialty",
                "pattern": "Specialty",
                "target": [
                    "masterTarget",
                    "Specialty"
                ]
            }, {
                "name": "Tests",
                "pattern": "Tests",
                "target": [
                    "masterTarget",
                    "Tests"
                ]
            }, {
                "name": "Support",
                "pattern": "Support",
                "target": [
                    "masterTarget",
                    "Support"
                ]
            }],
            "targets": {
                "masterTarget": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "masterPages",
                    "viewId": "idMaster",
                    "viewName": "Master",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Login": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "Login",
                    "viewName": "Login",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Dashboard": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idDashboard",
                    "viewName": "Dashboard",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Appointments": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idAppointments",
                    "viewName": "Appointments",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Doctors": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idDoctors",
                    "viewName": "Doctors",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Patient": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idPatient",
                    "viewName": "Patient",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Subscription": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idSubscription",
                    "viewName": "Subscription",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Symptoms": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idSymptoms",
                    "viewName": "Symptoms",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Specialty": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idSpecialty",
                    "viewName": "Specialty",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Tests": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idTests",
                    "viewName": "Tests",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                },
                "Support": {
                    "viewType": "XML",
                    "transition": "slide",
                    "controlAggregation": "detailPages",
                    "viewId": "idSupport",
                    "viewName": "Support",
                    "viewLevel": 1,
                    "controlId": "Splitapp"
                }
            }
        }

As you can see we have multiple detail page, and a common thing among all is “masterTarget”. This is the target for Master Page, i.e. “The left pane where you can have multiple tabs to switch pages”.

Master Page View:  Master.view.xml

<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"  xmlns:tnt="sap.tnt"
    controllerName="admin.admin.controller.Master" xmlns:html="http://www.w3.org/1999/xhtml">
    <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 text="Configuration" icon="sap-icon://overview-chart" key="Dashboard"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Appointments" icon="sap-icon://account" key="Appointments"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Doctors" icon="sap-icon://stethoscope" key="Doctors"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Patient" icon="sap-icon://wounds-doc" key="Patient"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Subscription" icon="sap-icon://collections-insight" key="Subscription"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Symptoms" icon="sap-icon://electrocardiogram" key="Symptoms"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Medical Specialty" icon="sap-icon://clinical-order" key="Specialty"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Tests" icon="sap-icon://clinical-tast-tracker" key="Tests"></tnt:NavigationListItem>
            <tnt:NavigationListItem text="Support" icon="sap-icon://headset" key="Support"></tnt:NavigationListItem>
            <!--<tnt:NavigationListItem text="Log Out" icon="sap-icon://log" key="LogOut"></tnt:NavigationListItem>-->
        </tnt:NavigationList>
        <footer>
            <OverflowToolbar>
                <Text text="{i18n>appVersion}"/>
                <ToolbarSpacer/>
            </OverflowToolbar>
        </footer>
    </Page>
</mvc:View>

Master Controller: Master.controller.js

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function (Controller) {
    "use strict";
    return Controller.extend("admin.admin.controller.Master", {
        /**
         * Called when a controller is instantiated and its View controls (if available) are already created.
         * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
         * @memberOf Healthbridge-admin.Healthbridge-admin.view.Master
         */
        onInit: function () {
            // Get Router Info
            this.oRouter = this.getOwnerComponent().getRouter();
        },
        /**
         * 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;
            sap.ui.core.BusyIndicator.show();
            // var sTimeOutErrorMsg = this.oBundle.getText("TimeOutError");
            var sError;
            var sToPageId = oEvent.getParameter("item").getKey();
            if (sToPageId) {
                try {
                    that.oRouter.navTo(sToPageId);
                } catch (err) {
                    if (err.statusCode === 401) {
                        // sError = sTimeOutErrorMsg;
                        window.location.reload(true);
                        sap.ui.core.BusyIndicator.hide();
                    } else {
                        sError = err.error;
                        sap.m.MessageBox.error(sError);
                        window.location.reload(true);
                        sap.ui.core.BusyIndicator.hide();
                    }
                    // window.location.href = '../logout';
                }
            } else {
                window.location.reload(true);
                sap.ui.core.BusyIndicator.hide();
            }
        }
    });
});

Apart from above, you can simply create your pages and controllers and keep linking them in master page and manifest file.

Changes in Detail Pages

In Detail pages, you need to handle a few things:

  • Within On Init or Route Matched section, you need to unhide Master Section, in this use case it is hidden, as first page was Login, and we don’t want to show Master section. The code is as below:
    // By default it is set "HideMode" 
    this.getView().getParent().getParent().setMode("ShowHideMode");
    // This is to hide the Master Button over the master page invisible
    this.getView().getParent().getParent()._oShowMasterBtn.setVisible(false);

    In case, you directly go to Master Detail Section, just delete the mode from App.view.xml

  • You can hide and unhide Master tab/section on click of a button whose code is mentioned below
    We have written the code for button press “onExpandPress”:
    Button code: <Button icon=”sap-icon://full-screen” tooltip=”{i18n>Expand}” press=”onExpandPress”/>
    Controller Code:

    /**
             * onExpandPress is invoked from UI on press of button Expand. 
             * Input: current mode -- Full Screen or Pane Screen
             * Output: opposite mode -- Pane Screen or Full Screen
             */
            onExpandPress: function (oEvent) {
                var navVisible = this.getView().getParent().getParent().getMode();
                if (navVisible === "ShowHideMode") {
                    this.getView().getParent().getParent().setMode("HideMode");
                    oEvent.getSource().setIcon("sap-icon://exit-full-screen");
                } else {
                    this.getView().getParent().getParent().setMode("ShowHideMode");
                    oEvent.getSource().setIcon("sap-icon://full-screen");
                }
                this.getView().getParent().getParent()._oShowMasterBtn.setVisible(false);
            },

     

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

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