Skip to Content
Technical Articles
Author's profile photo Former Member

Split-Screen In Fiori Made Easy!

Introduction

While working with the famous Master Detail or the Split Screen layout in Fiori, often we could come across situations where we need to explain the working mechanism of it to the beginners. This is especially true when we try to train a group of junior engineers coming from college and starting their career in SAPUI5. It could be easy as a pro to utilize the demo apps or utilize the templates available on SAP Web IDE to build a Master Detail app. However for someone starting their career directly in Fiori, it may not be the ideal place to start their journey. This post aim to detail the building of a Master Detail from scratch without using any template. Experienced members please ignore(we have the Flexible Column Layout). Some thing like the below shown on Fiori Design Guidelines is what we are trying to achieve:-

Fig 1): Split-Screen Layout in Fiori

Ok, let us get started.

Step1: Application Initializing

First of all we create a bare minimum SAPUI5 application(not the Master Detail template). We stick to the minimum version(1.38) available for selection the Web IDE.

Fig 2): Template and version selection in SAP Web IDE

Input the initial view as ‘App.view.xml’ and proceed. Once the project is created, open the ‘App.view.xml’ file and insert the “SplitApp” control as below:-

<mvc:View controllerName="com.demo.ZDemo_MasterDetail.controller.App" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml"
	displayBlock="true" xmlns="sap.m">
	<SplitApp id="idAppControl">
	</SplitApp>
</mvc:View>

Let us quickly try to see a preview of our application. Notice the screen split into two columns as below:-

Fig 3): Master Detail Screen split.

Let us  proceed to bring some life to the page.

Step 2: Loading Data, Setting Master

Now let us quickly set up required data and try to populate the Master list. For time being we are using a local json file as below, a list of tea/coffee types:-

{
	"drinks": [
		{
			"drinkId": 0,
			"drinkName": "Coffe",
			"products": [
				{
					"productId": 0,
					"productName": "Bru Coffe"
				},
				{
					"productId": 1,
					"productName": "Nescafe Coffe"
				},
				{
					"productId": 2,
					"productName": "Filter Coffe"
				},
				{
					"productId": 3,
					"productName": "Black Coffe"
				},
				{
					"productId": 4,
					"productName": "Bournvita Coffe"
				}
			]
		},
		{
		"drinkId": 1,
			"drinkName": "Tea",
			"products": [
				{
					"productId": 0,
					"productName": "Normal Tea"
				},
				{
					"productId": 1,
					"productName": "Lemon Tea"
				},
				{
					"productId": 2,
					"productName": "Ginger Tea"
				},
				{
					"productId": 3,
					"productName": "Black Tea"
				},
				{
					"productId": 4,
					"productName": "Masala Tea"
				}
			]
		}
	]
}

We create a new view by name ‘master’ under view folder and the controller created automatically under the controller folder accordingly.

Fig 4): Master view creation.

We bind the list and drink name to the master view as below:-

<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="com.demo.ZDemo_MasterDetail.controller.master"
	xmlns:html="http://www.w3.org/1999/xhtml">
	<App>
		<pages>
			<Page title="Orders List">
				<List id="orders" items="{/drinks}" mode="SingleSelectMaster" selectionChange="onSelectionChange">
					<items>
						<StandardListItem title="{drinkName}" type="Active" press="onSelectionChange"/>
					</items>
				</List>
			</Page>
		</pages>
	</App>
</mvc:View>

Now we move on to the routing part of the application as described in the standard documentation here. We set up a route and corresponding target for the master view in the “manifest.json” file as below:-

		"routing": {
			"config": {
				"routerClass": "sap.m.routing.Router",
				"viewType": "XML",
				"async": true,
				"viewPath": "com.demo.ZDemo_MasterDetail.view",
				"controlAggregation": "pages",
				"controlId": "idAppControl",
				"clearControlAggregation": false
			},
			"routes": [{
				"name": "master",
				"pattern": "",
				"target": ["master"]
			}],
			"targets": {
				"master": {
					"viewType": "XML",
					"transition": "slide",
					"clearControlAggregation": false,
					"viewName": "master",
					"controlAggregation": "masterPages",
					"viewLevel": 0
				}
			}
		}

Let us proceed to see the changes and check the Master list. It lists the type of drinks on the Mater view as expected. Right side of the application, the Detail area is still empty.

Fig 5): Master List populated.

We are going to populate the details of the item selected next.

Step 3: Displaying Details of Master Item

Similar to the earlier step, we proceed to create another view named ‘detail’ this time. Bind the product details to the controls as below:-

<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="com.demo.ZDemo_MasterDetail.controller.detail"
	xmlns:html="http://www.w3.org/1999/xhtml">
	<App>
		<pages>
			<Page title="{drinkName}" navButtonPress="onNavBack" showNavButton="{device>/system/phone}">
				<content>
					<List id="products" items="{products}" headerText="Products">
						<items>
							<StandardListItem title="{productName}" type="Active" press="onSelectionChange"/>
						</items>
					</List>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>

Then create a new route and assign the target view accordingly in the routing section as below:-

"routes": [
				{
					"name": "master",
					"pattern": "",
					"target": [
						"master"
					]
				},
				{
					"name": "drinkDetails",
					"pattern": "drinks/:drinkId:",
					"target": [
						"master",
						"drinkDetails"
					]
				}
			],
			"targets": {
				"master": {
					"viewType": "XML",
					"transition": "slide",
					"clearControlAggregation": false,
					"viewName": "master",
					"controlAggregation": "masterPages",
					"viewLevel": 0
				},
				"orderDetails": {
					"viewName": "Detail1",
					"controlAggregation": "detailPages",
					"viewLevel": 1
				}
			}

Also let us handle the selection change event on the master list. We take the id of the item selected on the master list and pass it to the pattern defined in routing section as below:-

onSelectionChange: function(oEvent) {
			var sOrderId = oEvent.getSource().getSelectedItem().getBindingContext().getProperty("drinkId");
			this.getOwnerComponent().getRouter()
				.navTo("drinkDetails", 
					{drinkId:sOrderId}, 
					!Device.system.phone);
		}

Corresponding on the detail controller, we have a routematched method to handle the detail page binding as below:-

onInit: function () {
			this.getOwnerComponent().getRouter().getRoute("drinkDetails").attachPatternMatched(this._onRouteMatched, this);
		},
		_onRouteMatched: function(oEvent) {
			this._drinkId = oEvent.getParameter("arguments").drinkId;
			this.getView().bindElement("/drinks/" + this._drinkId);
		}

Finally we have the Master Detail application showing the possible options for selection.

Fig 6): Details section populated based on the Master Item selection.

We could proceed to modify the application to incorporate more relevant content on the Master as well as on the Detail pages.

Result

It is very convenient to start with a “SplitApp” control and grow from there. If we have selected the ‘Master-Detail’ template and proceeds to OData service selection from the wizard(like SAP ES5 sytem – OData services), then if the association and navigation between Entity Sets are properly defined we could easily map Master List and Detail list via wizard itself as below:-

Fig 7): SplitApp creation via template in Web IDE.

However in some of the cases where you are starting on the project and have the Entity set for Master list only available, and want to proceed accordingly on the UI and later on build the Detail related sets(like in Agile methodology),provide association between them etc. later, then it would be a good idea to start prototyping on the UI side with a ‘SplitApp’ master list and proceed from there rather waiting for a full fledged OData service.

Full code available on GitRepo at FioriMasterDetail

Thanks,

Jakes

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo פאינה פרידמן
      פאינה פרידמן

      Very good explanation. Thanks

      Author's profile photo Toshana Dharamthok
      Toshana Dharamthok

      Good Explanation