I'm building a Room Booking System using SAP Fiori. Here's a requirement I have to implement:
In the page Find Room users will choose a room and a date, then take action onBookRoom. The action will navigate to the page Book Room which uses the template Form Entry Object Page, also passing the parameters DateScheduled and RoomID to this page. The Book Room page will assign these parameters' values to the fields DateScheduled and RoomID in the page.
The navigation worked, the parameters are passed into the Book Room page successfully.
My question is, how can I fill these parameters' values to DateScheduled and RoomID fields in page Book Room in SAP Fiori?
I've searched all over SAP Help forums but found no answer. There's an article which guides how to prefill fields but it performs from the backend, which seems unable to get the navigation parameters.
I'm using VSCode SAP Fiori Extension and OData V4 on backend, running a local Fiori launchpad with Fiori sandbox and NodeJS Express as the frontend server.
The entity bound to page Book Room has these fields:
key ScheduleId,
DateScheduled,
RoomId
fioriSandboxConfig.json
"zmrbsschedule-create": {
"semanticObject": "zmrbsschedulecreate",
"action": "create",
"title": "New Schedule",
"signature": {
"parameters": {
"DateScheduled": {
"required": false
},
"RoomId": {
"required": false
}
},
"additionalParameters": "allowed"
},
"resolutionResult": {
"applicationType": "URL",
"additionalInformation": "SAPUI5.Component=zmrbsschedulecreate",
"url": "./"
}
},
"zavailroom-display": {
"semanticObject": "zavailroom",
"action": "display",
"title": "Find Available Rooms",
"signature": { "parameters": {}, "additionalParameters": "allowed" },
"resolutionResult": {
"applicationType": "URL",
"additionalInformation": "SAPUI5.Component=zavailroom",
"url": "./"
}
},
ToBookRoom.controller.js (controller extension in page Find Room)
sap.ui.define(['sap/ui/core/mvc/ControllerExtension'], function (ControllerExtension) {
'use strict';
return ControllerExtension.extend('zavailroom.ext.controller.ToBookRoom', {
// this section allows to extend lifecycle hooks or hooks provided by Fiori elements
override: {
/**
* 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 zavailroom.ext.controller.ToBookRoom
*/
onInit: function () {
// you can access the Fiori elements extensionAPI via this.base.getExtensionAPI
var oModel = this.base.getExtensionAPI().getModel();
}
},
onBookRoom: async function () {
const oAPI = this.base.getExtensionAPI();
const ctx = oAPI.getBindingContext();
const roomId = ctx.getProperty("RoomID");
const dateSche = ctx.getProperty("DateSche");
// sap.ushell.Container
const Navigation= await sap.ushell.Container.getServiceAsync("Navigation");
// trigger navigation
Navigation.navigate({
target: { semanticObject: "zmrbsschedulecreate", action: "create" },
params: {
RoomId: roomId,
DateScheduled: dateSche
}
});
}
});
});
CreateScheduleController.controller.js (controller extension in page Book Room)
sap.ui.define(['sap/ui/core/mvc/ControllerExtension'], function (ControllerExtension) {
'use strict';
return ControllerExtension.extend('zmrbsschedulecreate.ext.controller.CreateScheduleController', {
// this section allows to extend lifecycle hooks or hooks provided by Fiori elements
override: {
/**
* 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 zmrbsschedulecreate.ext.controller.CreateScheduleController
*/
onInit: function () {
// you can access the Fiori elements extensionAPI via this.base.getExtensionAPI
var oModel = this.base.getExtensionAPI().getModel();
},
onAfterRendering: async function () {
console.log("CreateScheduleController loaded");
const oComponent = this.getView().getController().getAppComponent();
const oParams = oComponent.getComponentData()?.startupParameters || {};
console.log("Startup parameters:", oParams);
console.log("RoomId:", oParams.RoomId);
console.log("DateScheduled:", oParams.DateScheduled);
console.log("preferredMode:", oParams.preferredMode);
var oModel = this.base.getExtensionAPI().getModel();
console.log("Model:", oModel);
const oContext = this.base.getExtensionAPI().getBindingContext();
console.log("Context:", oContext);
if (!oContext) {
console.warn("No binding context available.");
return; // no create context yet
}
// ---- SET FIELDS HERE ----
if (oParams.RoomId) {
oContext.setProperty("RoomId", oParams.RoomId[0]);
}
if (oParams.DateScheduled) {
oContext.setProperty("DateScheduled", oParams.DateScheduled[0]);
}
}
}
});
});
I tried to fill fields DateScheduled and RoomID here, by using setProperty() on the binding context, but the binding context is undefined. The startupParameters does have the parameter values I passed from Find Room. Is this the right way? Or I must prefill fields somewhere else?