In many project use cases, we often encounter situations where the validity of one field depends on the value of another. For example, when a flag is updated or a key date is modified, the user must provide additional comments before saving the record.
In this blog post, I’ll walk you through how I implemented such conditional validations in a Fiori Elements Object Page using Controller Extensions.
Scenario
I had a requirement where:
If the Last Working Date (LWD) was changed, then the Additional Comments (ARD Comments) field must not be empty.
If certain flags or dropdown values were set to specific conditions (like “Y” or a specific code), corresponding comment fields were required before allowing the user to save.
Instead of modifying the generated metadata or annotations, I handled these validations using the Controller Extension’s beforeSaveExtension hook, which is triggered before the save action.
Implementation
1. Adding controller extension :- Add the controller extension file in app/webapp/ext/controller as ObjectPageExt.controller.js
2. Add the controller file in manifest.json
“sap.ui5”: {
“flexEnabled”: true,
// other fields
“resources”: {
“css”: []
},
“routing”: {
“config”: {},
“routes”: [],
“targets”: {}
},
“extends”: {
“extensions”: {
“sap.ui.controllerExtensions”: {
“sap.suite.ui.generic.template.ObjectPage.view.Details”: {
“controllerName”: “app.ext.controller.ObjectPageExt”
}
}
}
}
},
3. ObjectPageExt.controller.js
sap.ui.define([“sap/ui/core/mvc/ControllerExtension”, “sap/m/MessageBox”], function (ControllerExtension, MessageBox) {
“use strict”;
return ControllerExtension.extend(“offboardingdashboard.ext.controller.ObjectPageExt”, {
override: {
beforeSaveExtension: function () {
const oContext = this.getView().getBindingContext();
if (!oContext) return Promise.resolve();
const oModel = oContext.getModel();
const sPath = oContext.getPath();
const oNewData = oContext.getObject(); // Current draft data
// — Step 1: Get the original (active) entity data —
const oOriginalData = oModel.getOriginalProperty
? oModel.getOriginalProperty(sPath)
: null;
// — Step 2: Detect change in Last Working Date —
let bLwdChanged = false;
if (oOriginalData && oOriginalData.cust_lastworkingdate && oNewData.cust_lastworkingdate) {
const dNew = new Date(oNewData.cust_lastworkingdate);
const dOld = new Date(oOriginalData.cust_lastworkingdate);
bLwdChanged = dNew.getTime() !== dOld.getTime();
} else if (oOriginalData && oOriginalData.cust_lastworkingdate !== oNewData.cust_lastworkingdate) {
bLwdChanged = true;
}
// — Step 3: Apply validation rules —
const aMessages = [];
if (oNewData.cust_rehire === “Y” && (!oNewData.cust_rehirecomments || oNewData.cust_rehirecomments.trim() === “”)) {
aMessages.push(“• Rehire comments are required when rehire flag is set to ‘Yes’.”);
}
if (bLwdChanged && (!oNewData.cust_ardcomments || oNewData.cust_ardcomments.trim() === “”)) {
aMessages.push(“• ARD comments are required when Last Working Date has been changed.”);
}
// — Step 4: Show error message and prevent save —
return new Promise(function (fnResolve, fnReject) {
if (aMessages.length > 0) {
const sMessage = “Please address the following issues before saving:nn” + aMessages.join(“n”);
MessageBox.error(sMessage, {
actions: [MessageBox.Action.OK],
onClose: fnReject
});
} else {
fnResolve();
}
});
}
}
});
});
How It Works
The beforeSaveExtension method is triggered automatically before the Save action on the Object Page.
We first read the current draft data and the original active entity.
We compare fields like cust_lastworkingdate to detect changes.
Based on certain conditions (like flag = ‘Y’ ), we push validation messages into an array.
If there are validation errors, a MessageBox appears with all issues listed, and the save action is prevented.
UI Screenshots
When both the conditions are met :
-> last working day is changed and rehire flag is set to ‘Y’
-> only last working day is changed
-> only rehire flag is set to ‘Y’
Key Takeaways
Always perform value-dependent validations in the beforeSaveExtension hook for extensibility.
Use getOriginalProperty to safely compare values between draft and active entities.
Consolidate all validation messages for a better user experience rather than showing multiple alerts.
In many project use cases, we often encounter situations where the validity of one field depends on the value of another. For example, when a flag is updated or a key date is modified, the user must provide additional comments before saving the record.In this blog post, I’ll walk you through how I implemented such conditional validations in a Fiori Elements Object Page using Controller Extensions.ScenarioI had a requirement where:If the Last Working Date (LWD) was changed, then the Additional Comments (ARD Comments) field must not be empty.If certain flags or dropdown values were set to specific conditions (like “Y” or a specific code), corresponding comment fields were required before allowing the user to save.Instead of modifying the generated metadata or annotations, I handled these validations using the Controller Extension’s beforeSaveExtension hook, which is triggered before the save action.Implementation1. Adding controller extension :- Add the controller extension file in app/webapp/ext/controller as ObjectPageExt.controller.js2. Add the controller file in manifest.json”sap.ui5″: {
“flexEnabled”: true,
// other fields
“resources”: {
“css”: []
},
“routing”: {
“config”: {},
“routes”: [],
“targets”: {}
},
“extends”: {
“extensions”: {
“sap.ui.controllerExtensions”: {
“sap.suite.ui.generic.template.ObjectPage.view.Details”: {
“controllerName”: “app.ext.controller.ObjectPageExt”
}
}
}
}
},3. ObjectPageExt.controller.jssap.ui.define([“sap/ui/core/mvc/ControllerExtension”, “sap/m/MessageBox”], function (ControllerExtension, MessageBox) {
“use strict”;
return ControllerExtension.extend(“offboardingdashboard.ext.controller.ObjectPageExt”, {
override: {
beforeSaveExtension: function () {
const oContext = this.getView().getBindingContext();
if (!oContext) return Promise.resolve();
const oModel = oContext.getModel();
const sPath = oContext.getPath();
const oNewData = oContext.getObject(); // Current draft data
// — Step 1: Get the original (active) entity data —
const oOriginalData = oModel.getOriginalProperty
? oModel.getOriginalProperty(sPath)
: null;
// — Step 2: Detect change in Last Working Date —
let bLwdChanged = false;
if (oOriginalData && oOriginalData.cust_lastworkingdate && oNewData.cust_lastworkingdate) {
const dNew = new Date(oNewData.cust_lastworkingdate);
const dOld = new Date(oOriginalData.cust_lastworkingdate);
bLwdChanged = dNew.getTime() !== dOld.getTime();
} else if (oOriginalData && oOriginalData.cust_lastworkingdate !== oNewData.cust_lastworkingdate) {
bLwdChanged = true;
}
// — Step 3: Apply validation rules —
const aMessages = [];
if (oNewData.cust_rehire === “Y” && (!oNewData.cust_rehirecomments || oNewData.cust_rehirecomments.trim() === “”)) {
aMessages.push(“• Rehire comments are required when rehire flag is set to ‘Yes’.”);
}
if (bLwdChanged && (!oNewData.cust_ardcomments || oNewData.cust_ardcomments.trim() === “”)) {
aMessages.push(“• ARD comments are required when Last Working Date has been changed.”);
}
// — Step 4: Show error message and prevent save —
return new Promise(function (fnResolve, fnReject) {
if (aMessages.length > 0) {
const sMessage = “Please address the following issues before saving:nn” + aMessages.join(“n”);
MessageBox.error(sMessage, {
actions: [MessageBox.Action.OK],
onClose: fnReject
});
} else {
fnResolve();
}
});
}
}
});
});How It WorksThe beforeSaveExtension method is triggered automatically before the Save action on the Object Page.We first read the current draft data and the original active entity.We compare fields like cust_lastworkingdate to detect changes.Based on certain conditions (like flag = ‘Y’ ), we push validation messages into an array.If there are validation errors, a MessageBox appears with all issues listed, and the save action is prevented.UI Screenshots When both the conditions are met :-> last working day is changed and rehire flag is set to ‘Y’-> only last working day is changed-> only rehire flag is set to ‘Y’ Key TakeawaysAlways perform value-dependent validations in the beforeSaveExtension hook for extensibility.Use getOriginalProperty to safely compare values between draft and active entities.Consolidate all validation messages for a better user experience rather than showing multiple alerts. Read More Technology Blog Posts by SAP articles
#SAP
#SAPTechnologyblog