cancel
Showing results for 
Search instead for 
Did you mean: 

SAPUI5 app routing and navigation not working when run in Fiori launchpad using semantic objects

antonette_oberholster
Active Contributor

Hi guys

I've been following this guide:

Best Build Fiori Apps Rule 7: Always use intent-based navigation to navigate within an app and betwe...

But I still don't understand how we link intent based navigation (#SemanticObject-Action) to local routing and navigation using router in the manifest (routes and targets: #employees/{employeeId}

I'm using the sample app to guide me with local routing using the .navTo() funtion:

Sample: Navigation - Step 10 - Implement Lazy Loading

All the routing in my app works 100% when I run it outside the Fiori Launchpad, but as soon as I run it inside the Fiori Launchpad, the local navigation and routing stops working.

Outside Fiori Launchpad:

http://<server>:<port>/<path_to_app>/myApp/index.html

Routing works fine:

http://<server>:<port>; /<path_to_app>/myApp/index.html#employees/{employeeId}

Inside Fiori Launchpad

http://<server>:<port>; /<path_to_flp>/FioriLaunchpad.html#MySemanticObject-create

Routing does not work

http://<server>:<port>; /<path_to_flp>/FioriLaunchpad.html#MySemanticObject-create <How do you add local navigation #employees/{employeeId} to a url that already contains a # value for the semantic object?>

When I click on the buttons to navigate to other views nothing happens, there are no errors in the console.

How can I get my local navigation to work inside Fiori Launchpad using Semantic Objects?

Thanks

Antonette

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member

Hi Antonette,

For cross application routing, you have to use:

var crossAppNav = sap.ushell.Container.getService("CrossApplicationNavigation")

To add the local navigation #employees/{employeeId} to a url that already contains a # value for the semantic object you have to pass param to it.

var empHash = (crossAppNav && crossAppNav.hrefForExternal({
  target:{
  semanticObject:"MySemanticObject",
  action:"create"},
  params:{"employeeId": "12631" }}))||""; crossAppNav.toExternal({
  target:{
  shellHash: empHash}});

Then, in onRouteMatched event of first page in Employee App you have to get the startup parameter to get the employee ID.

var startupParam = this.getOwnerComponent().getComponentData().startupParameters;
var empId = startupParam.employeeId;

Based on this value you can internally navigate to the local route using router.navTo function.

Regards,

Nikhil

antonette_oberholster
Active Contributor
0 Kudos

Thank you so much for this helpful guide Nikhil.

#ZEHS_Airborne_Semantic-create takes you to my main view:

Clicking on the button "Create" takes you to my Detail view (see code below). I'm using the lazy loading of views to populate tabs on my detail page and routing to navigte between the views inside the tabs ( see this sample for concept Sample: Navigation - Step 10 - Implement Lazy Loading)

This is what my code looks like:

Manifest

"routing": {
			"config": {
				"routerClass": "sap.m.routing.Router",
				"viewType": "XML",
				"viewPath": "ehs.airborneComponent.view",
				"controlId": "idAppControl",
				"controlAggregation": "pages",
				"transition": "show",
				"bypassed": {
					"target": "notFound"
				},
				"async": true,
				"viewLevel": 1
			},
			"routes": [
				{
					"name": "main",
					"pattern": "",
					"target": "main"
				},
				{
					"pattern": "detail:?query:",
					"name": "detail",
					"target": "detail"
				}
			],
			"targets": {
				"main": {
					"viewName": "Main",
					"viewId": "main"
				},
				"notFound": {
					"viewName": "NotFound",
					"viewId": "notFound"
				},
				"detail": {
					"viewName": "Detail",
					"transition": "flip"
				},
				"detailTabPre": {
					"parent": "detail",
					"viewName": "DetailPre",
					"viewId": "DetailPreId",
					"controlId": "preTab",
					"controlAggregation": "content"
				}
			}
		}

Main Controller (click create button to navigate to detail page)

onCreate : function (){
	console.log("Main Controller - onCreate");
	this.getRouter().navTo("detail", true /*without history*/); // Routes/navigates to "#/detail (No tab, _onRouteMatched in Detail Controller will handle default: Pre)
}, 

Detail Controller

var _aValidTabKeys = ["Info", "Projects", "Pre", "Detail"];

return BaseController.extend("ehs.airborneComponent.controller.Detail", {
		onInit: function () {
			console.log("Detail Controller - onInit");
			var oRouter = this.getRouter(); // comes from BaseController
			oRouter.getRoute("detail").attachMatched(this._onRouteMatched, this); // set _onRouteMtched as the event that fires when navigation occurs
		},
		
		_onRouteMatched : function (oEvent) {
			console.log("Detail Controller - _onRouteMatched");
			var oArgs, oView, oQuery;
			oArgs = oEvent.getParameter("arguments"); // returns object {?query: {tab: "Pre"}}
			oView = this.getView();
						
			oQuery = oArgs["?query"]; // returns object {tab: "Pre"}
			if (oQuery && _aValidTabKeys.indexOf(oQuery.tab) > -1){
				oView.getModel("detailView").setProperty("/selectedTabKey", oQuery.tab); // Returns property "tab" -> oQuery.tab = oArgs["?query"].tab = "Pre"
				// support lazy loading for the Pre and Detail tab
				if (oQuery.tab === "Pre" || oQuery.tab === "Detail"){
					// the target is either "detailTabPre" or "detailTabDetail"
					this.getRouter().getTargets().display("detailTab" + oQuery.tab); // "detailTabPre" or "detailTabDetail"
				}
			} else {
				// the default query param should be visible at all time
				this.getRouter().navTo("detail", {
					query: {
						tab : _aValidTabKeys[0] // Info
					}
				},true /*no history*/ ); 				
			}
		},

Detail View

<mvc:View controllerName="ehs.airborneComponent.controller.Detail" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
	xmlns:core="sap.ui.core" xmlns:layout="sap.ui.layout" xmlns="sap.m" xmlns:f="sap.f" displayBlock="true">
	<Page
		title="{i18n>detailTitle}"
		id="detailPageId"
		showNavButton="true"
		navButtonPress="onNavBack">
		<content>
			<IconTabBar
				id="iconTabBarDetailId"
				select="onTabSelect"
				selectedKey="{detailView>/selectedTabKey}">
				<items>
					<IconTabFilter id="infoTab" text="{i18n>Pre}" key="Info">
						<Text text="Display Pre Content Here" />
					</IconTabFilter>
					<IconTabFilter id="projectsTab" text="{i18n>Projects}" key="Projects">
						<mvc:XMLView viewName="ehs.airborneComponent.view.Main"></mvc:XMLView>
					</IconTabFilter>
					<IconTabFilter id="preTab" text="Pre" key="Pre">
						<!-- place content via lazy loading -->
					</IconTabFilter>
					<IconTabFilter id="notesTab" text="Detail" key="Detail">
						<!-- place content via lazy loading -->
					</IconTabFilter>
				</items>
			</IconTabBar>
		</content>
	</Page>
	
</mvc:View>

PS - it works when it is not run in the fiori launchpad

Thanks

Antonette

Former Member
0 Kudos

May you please share screenshot of error which you are getting while running in launchpad. And please share console error (if any) as well.

Regards,

Nikhil

christian102094
Participant

Not sure if this is useful but in my app it's something like this:

https://flpnwc-xxxxxxxx.dispatcher.us2.hana.ondemand.com/sites/haydukapp#haydukapp-Display&/DetalleDeSolicitudesDeAprobacionDeEmbarcaciones/ShipownerSet(Ruc='111',Origin='T',Status='P',Request='0000000287')

where "#haydukapp-Display" is the intent-action and &/Detalle.... is the routing.

antonette_oberholster
Active Contributor
0 Kudos

Thanks Christian

Using this url syntax I get the "Not found" page . . . can you please show me what your targets look like? Are you using the .navTo() function to navigate?

Regards

Antonette

christian102094
Participant

The targets look like this:

"targets": {
    ...
    "AprobacionDeSolicitudesEmbarcaciones": {
        "controlAggregation": "pages",
        "viewName": "AprobacionDeSolicitudesEmbarcaciones",
        "viewId": "AprobacionDeSolicitudesEmbarcaciones",
        "viewLevel": 8,
        "transition": "slide"
    },
    "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones": {
        "controlAggregation": "pages",
        "viewName": "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones",
        "viewId": "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones",
        "viewLevel": 9,
        "transition": "slide"
    }
}

The routes look like this:

"routes": [
    ...
    {
        "pattern": "AprobacionDeSolicitudesEmbarcaciones/:context:",
        "name": "AprobacionDeSolicitudesEmbarcaciones",
        "target": [
            "AprobacionDeSolicitudesEmbarcaciones"
        ]
    },
    {
        "pattern": "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones/:context:",
        "name": "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones",
        "target": [
            "DetalleDeSolicitudesDeAprobacionDeEmbarcaciones"
        ]
    }
]

And the navTo call looks like this:

var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
...
oRouter.navTo("DetalleDeSolicitudesDeAprobacionDeEmbarcaciones", {
    context: sContext
});
nicoschoenteich
Developer Advocate
Developer Advocate
0 Kudos

This works. Thanks!

SergioG_TX
Active Contributor
0 Kudos

i did a google search on sapui5 routing navigation and semantic objects... this is what i found:

https://blogs.sap.com/2016/06/20/cross-application-navigation-between-sapui5-applications/

is that what you were lookign for?

antonette_oberholster
Active Contributor
0 Kudos

Thanks Sergio, I'm reading through it now, but this focuses on cross app navigation, I just want to navigate between views in the same app