Introductory Guide to SAPUI5 Routing

This guide will introduce you to the basics of SAPUI5 routing. You will learn the purpose of routing, how to implement it, and why you should use it. You can follow my steps to create your own application using routing. All the source code will be made available for download.

Introduction

Before we begin coding let’s take a look at the purpose of routing and why you should use it. Routing allows users to navigate to any point within the application. You can even pass variables to show the correct tab or item once the designated view is reached. This allows users to bookmark URLs to return to views later and the sharing of URLs, thus anyone can quickly get to the same page and dataset as them.  Since SAPUI5 applications run in a web browser this sort of behavior is expected amongst users.  There may be a time when you have two completely different applications that share a similar dataset and you may want to navigate out of application 1 and into application 2, to get some different functionality, but you want to retain working on the same data item you had in application 1.  This can easily be made possible through routing.

Screenshots – The Application Completed

Home page of application with no routing, you can see there is no hash in URL

No SAPUI5 Routing Hash

 

-Tab filter route matched with “two” has an optional parameter. View is shown with second tab selected

SAPUI5 Routing with hash and one parameter

-Catch all route was used since no routes could match the URL hash

SAPUI5 Routing that does not exist

 

SAPUI5 Routing Implementation

image08

Line 12 is important because that is where I have stated to use my namespace jim.routing as the resource roots. Jim comes from my name and routing because that is what the project is for. Your name space can be whatever you want, it is common for the company name to come first and then the application’s name. Next we add lines 16 – 22 to create a shell and ComponentContainer. ‘name’ is used to declare our namespace, and we place the shell at the div tag with id equal to ‘content’.  Now that our shell and Component Container are created, our Component.js gets used.

image14

When the componentContainer gets created the Component’s createContent method gets called. In here we create a splitApp (line 6) and a model (line 8-9). The model is using mock json and is set to the entire application. Line 11 initializes all of our routes, which we will see in a second. And line 13 returns our splitApp so it can be used and shown. Below are the configured routes:

SAPUI5 Routes defined

The routing config and routes get defined under the metadata object. And are initialized from line 11. The config defines all of the default values for a route unless otherwise specified. So by default a route will create a view assuming it’s from an XML file because viewType is set to XML on line 18. The viewPath (line 19) is the default directory for the view files. Notice my namespace comes first and then the folder ‘view’ where the view files are located. Line 20 targetAggregation is the aggregation of a control that our view will be placed. Our targetControl (line 21) is our splitApp, we specify its ID which happens to also be “splitApp”. This splitApp control has two aggregations, they are masterPages and detailPages. We set the targetAggregation to detailPages, so unless otherwise specified in a route, the view will be loaded into the detailPages (right side) of the splitApp. And lastly line 22 sets clearTarget to be false. If clear target was true then by default whenever we load a new view into an aggregation the previous views would be cleared. However we don’t want this to happen because we plan on loading 3 views into the detailPages and want navigation between them to be quick.

 

Now for the routes.  We declare an array of objects called routes, to hold each route object (line  25). And each route object can have its own array of routes known as subroutes, seen on line 30. The only thing a route object needs to be a valid route is a unique name, although the route will be useless. Looking at the first route, we call it the master route, line 27. One line back (26) we state that this route matches the pattern “” which is blank or empty string in the URL hash.  If that pattern matches then the view to be loaded is called “Master” (line 28). Remember this route also uses all the default values set in the config. So this route also knows the view is an XML format and that it is located in the ‘view’ folder. But we specified the target Aggregation to be masterPages (line 29) so that is where this view will be displayed, on the left, the master side, of the splitApp.  Now if we view our app at “/index.html” the blank pattern matches because there is no hash present. Note that “index.html#” also matches blank (empty) pattern as ‘#’ is the start of the hash in the URL for a pattern to match.  The master view will now be loaded and visibible in the splitApp. But what about the detail side?

 

Since our first route named “master” matched, its sub routes will also now be checked. We can see there are two sub routes, named “welcome” and “tabfilter”.  The “welcome” route also has a pattern of “” blank or empty.  So our Welcome view will be loaded and placed in the detailPages of our splitApp. This is what we want and expect for a new user visiting our app, perhaps for the first time, which has no hash in the URL.  It is important to note that we could have given this route a pattern of say “welcome”, and if our URL looked like ‘***/index.html#welcome’ we would still get the same result of both master and detail views being loaded because their respected routes matched. Technically there is a blank or empty string in front of the string “welcome” in the hash, so that route matched, then the pattern or all the characters for “welcome” in the sub route were found and matched. Go ahead and try for yourself, it will take some playing around to fully understand. Now would also be a good time to mention that the routes act like a block of “else if” statements.  Meaning as soon as one route is matched no other routes below it will be tested for a match. Only the sub routes of that route will then be checked. So the order of your routes and where you put your sub routes will be very important. For example putting your catch all route first instead of last would mean your important routes will never be matched, because the catch all route will match everything and resolve.

 

The second sub route named “tabfilter” has an interesting pattern. It has both a static pattern to match, “tabfilter/” and an optional variable that can be passed in called ‘tab’.  This optional variable will be dynamic in that it will become any value in the URL after the “tabfilter/”. For example if the URL were “index.html#tabfilter/three” then ‘tab’ would become “three”. We can designate optional variables in the pattern with colons, so the URL “index.html#tabfilter/” will still match the route’s pattern but ‘tab’ will be null. If you want to require variables in the pattern then wrap the variable name in  ‘{ }’ curly brackets, and if there is not a string in the hash to assign to that variable the pattern will fail, resulting in no match.  The purpose of the tabfilter route is for a user to land on a specific details page with a specific tab open without having to first navigate to that page and then select the desired tab. This way a user can copy the URL they are on and share it with others, and the receiver will be on the correct page and already have the correct tab open.  Routes are not all magic however, they have changed the way views are created and loaded in code, but we still have to code methods in the controllers on what to do when a route is matched. Which we will get too momentarily.

 

The final route at the end is our catch all route, named “catchAllMaster”.  This route doesn’t have a pattern so will always trigger regardless of what the hash is, and only if no other route was matched before it. This route simply loads our master list view into the masterPages of the splitApp. Then it has a subroute with an optional variable of ‘:all*:’. Which means if there is any sort of hash all of it will match.  If there is a hash and we are in this route then we can safely assume that this hash is garbage since no other route matched it.  So that catchAllDetail route can load the notFound view into the detailPages (right side) of the splitApp. Now that we have seen all the routes and how they are initialized let’s look at the views and controllers to see how they handle a route that gets matched.

Useful Links

Officialy SAPUI5 Routing and Navigation Documentation

SAPUI5 Routing and changing URL dynamically – video guide

 

3 Responses

  1. Tanner Hyer says:

    Thanks for the guide, this help me to understand the basics.

  2. Alan Larabell says:

    Easy to follow, SAPUI5 Routing made easy.

  3. Kathaleen Ferrante says:

    Thanks For The High Performance SSD Cloud Hosting!

Leave a Reply

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