JavaScript Reference

Custom/Additional Javascript Functions can be defined inside a Javascript Control in the workbench. This can then be called from different execution points within the project. A function from a script created in a page can be called and executed from different pages. For example, defining a function and assigning it in the onLoad property of a Page or calling a script inside an Input Control when the value changes. 

Inside the Javascript Editor, a set of Useful Functions is provided to further assist the developer.

A classic and advanced Javascript editors are available. By default the classic editor is activated and it can be switched to the advanced editor by going to the menu bar and selecting Settings--->Options-→Advanced Javascript Editor

DescriptionSample
Prevent Refreshing Table Control

function init(){
var oTable = getControl("vendorListT");
oTable.setNoAutoLoad(true);

Trigger action on select record in a table

oTable.attachSelect(function(evt){
tableRowSelected(evt);
});


function tableRowSelected(evt){
console.log("table Row Selected");
var recordChosen = evt.getParameter("listItem").getBindingContext().getObject();
console.log(recordChosen.vendorName);
if(recordChosen.vendorName!=="(Vendor not in the list. Request new vendor)"){
//setField("vendorDetailsVisibile","true");
//Check if possible to extend to cc
var companyCode = getField("DFSICompanyCode");
initModel("searchhelps","/sap/opu/odata/sap/ZFAB_TS_SERVICESN");

var oModel = getModel("searchhelps");
var filters = [];
var oFilter = new sap.ui.model.Filter("Id", sap.ui.model.FilterOperator.EQ, recordChosen.vendorNo);
filters.push(oFilter);
var oFilterCC = new sap.ui.model.Filter("CC", sap.ui.model.FilterOperator.EQ, companyCode);
filters.push(oFilterCC);

var oPath = "/VendorCCCheckList";
oModel.read(oPath, {
success: function(data) {
for(var i in data.results){
var oResult = data.results[i];
console.log(oResult.Result);

jQuery.sap.require("sap.m.MessageBox");
var strHTML = "Vendor: " + oResult.Id + " - " + recordChosen.vendorName + "\n\n" + "Trading As: " + oResult.Name2 + "\n\n" + "Trading As: " + oResult.Name3 + "\n\n" + "Street: " + oResult.Street + "\n\n" + "City: " + oResult.City + "\n\n" + "State: " + oResult.State + "\n\n" + "Country: " + oResult.Country + "\n\n" + "PO Box: " + oResult.PO + "\n\n" + "PO Box City: " + oResult.POCity + "\n\n" + "PO Box State: " + oResult.POState + "\n\n" + "PO Box Country: " + oResult.POCountry + "\n\n" + "Blocked: " + oResult.Blocked + "\n\n" + "Purchasing Blocked: " + oResult.PBlocked + "\n\n" + "Deleted: " + oResult.Deleted;
sap.m.MessageBox.show(strHTML , {
title: "Vendor Details",
onClose: null
});
setField("EVendorNo",recordChosen.vendorNo);
setField("vname1",recordChosen.vendorName);
setField("name2",oResult.Name2);
setField("name3",oResult.Name3);
setField("searchTerm1",oResult.STerm1);
setField("industry",oResult.Industry);
setField("centralBlockIndicator",oResult.Blocked);
setField("purchasingBlockIndicator",oResult.PBlocked);

if(oResult.Result=="CC Exists"){
setField("unableExtendVisible", "true");
setField("extendVendorVisibile", "false");
setField("newVendorVisible", "false");
setField("newVendFieldVisible", "false");
setField("formShow", "false");
setField("extendVendFieldVisible", "false");
setField("newVendFieldEnabled", "false");
setField("CommentsVisible", "false");
}else{
setField("unableExtendVisible", "false");
setField("extendVendorVisibile", "true");
setField("newVendorVisible", "false");
setField("newVendFieldVisible", "false");
setField("formShow", "false");
setField("extendVendFieldVisible", "false");
setField("newVendFieldEnabled", "false");
setField("CommentsVisible", "false");
}
}
},
filters:filters
});
}else{
setField("EVendorNo","");
setField("vname1","");
setField("name2","");
setField("name3","");
setField("searchTerm1","");
setField("vendorDetailsVisibile","false");
setField("newVendorVisible","true");
setField("unableExtendVisible","false");
setField("extendVendorVisibile","false");
setField("newVendFieldVisible", "false");
setField("formShow", "false");
setField("extendVendFieldVisible", "false");
setField("newVendFieldEnabled", "false");
}
};

Set Max Length in an Input field

getControl("VendorNameId").setProperty("maxLength",40);

Call oData from script

initModel("searchhelps","/sap/opu/odata/sap/ZFAB_TS_SERVICESN");
var oModel = getModel("searchhelps");
var oPath = "/BankList";
oModel.read(oPath, {
success: function(data) {
_bsb = data.results;
}
});

Bind Visibility PropertygetControl("ApproverErrorId").getParent().bindProperty("visible","ApproverError");
Validate Email address - Input Field
validate email address
function validateEmail(evt) {
	//Reference: https://emailregex.com/
	var rexEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
	var lv_input = evt.getParameters().newValue;
	var validEmail = false;
	if (!lv_input.match(rexEmail)) {
		setControlState(evt.getSource().getId(), "Error", "'" + lv_input + "' is not a valid email address", true);
	} else {
		setControlState(evt.getSource().getId(), "None", "", false);
		validEmail = true;
	}
	setField("validEmail", validEmail);
}
Validate Phone number - Input field
function validatePhoneNumber(evt) {
	//Reference: https://digitalfortress.tech/tricks/top-15-commonly-used-regex/
	var rexPhone = /^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/;
	var lv_input = evt.getParameters().newValue;
	var validPhone = false;
	if (!lv_input.match(rexPhone)) {
		setControlState(evt.getSource().getId(), "Error", "'" + lv_input + "' is not a valid phone number", true);
	} else {
		validPhone = true;
		setControlState(evt.getSource().getId(), "None", "", false);
	}
	setField("validPhone", validPhone);
}
 Calling *SAP Search Help using JavaScript

        

initModel("searchhelps","/sap/opu/odata/iqx/SERVICES_SRV"); 
var oModel = getModel("main");
var filters = [];
var oFilter = new sap.ui.model.Filter("Config",  sap.ui.model.FilterOperator.EQ, "H_T047A::MAHNA,TEXTM:");
                filters.push(oFilter);
oFilter = new sap.ui.model.Filter("Name",  sap.ui.model.FilterOperator.EQ, testText);
                filters.push(oFilter);

                var oPath = "/GenSearchHelp";
                oModel.read(oPath, {
                    success: function(data) { 
                        for(var i in data.results){
                            var oResult = data.results[i];
                            setField("dunningtext",oResult.Name);
                            found = "X";
                        }              
                    },
                    filters:filters
                }); 

 Scroll to an element in a page

getControl("ReviewAndSubmit").scrollToElement(getControl("1Employeeid"));

"ReviewAndSubmit" is the page ID and "1Employeeid" is the element ID within the page

Highlight fields in the table

//Add style

    var oTableData = getControl("dataTable");
    var oBinding = oTable.getBinding("items");
    var length = oBinding.iLength;

    for(var i in length){

        var oRow = oTableData.getItems()[i];

        controlPosition = 1; //Position of the field in the column

        oControl = oRow.getCells()[controlPosition]; 

        oControl.addStyleClass("myErrorState");

        }


//Remove Style

        controlPosition = 1; //Position of the field in the column

        oControl = oRow.getCells()[controlPosition]; 

        oControl.removeStyleClass("myErrorState");


Enable wrapping of label

Add in CSS:

.sapMLabel {
white-space: pre-wrap;
}

ABN Validation (Australia)

var d1,d2,d3,d4,d5,d6,d7,d8,d9,d10, d11, tot, rem, ok;

var str = '51 824 753 556';

var replaced = str.split(' ').join('');

str = replaced;

   d1 = str.substr(0,1);

   parseInt(d1);

if ( d1 > 0 ) {

d1 = d1 - 1;

}

d1 = d1 * 10;

d2 = str.substr(1,1) * 1;

d3 = str.substr(2,1) * 3;

d4 = str.substr(3,1) * 5;

d5 = str.substr(4,1) * 7;

d6 = str.substr(5,1) * 9;

d7 = str.substr(6,1) * 11;

d8 = str.substr(7,1) * 13;

d9 = str.substr(8,1) * 15;

d10 = str.substr(9,1) * 17;

d11 = str.substr(10,1) * 19;

tot = d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 + d11;

rem = tot % 89;

if ( rem === 0 ) {

ok = 'true';

}else {

ok = 'false';

}

var d1,d2,d3,d4,d5,d6,d7,d8,d9,d10, d11, tot, rem, ok;

var str = '51 824 753 556';

var replaced = str.split(' ').join('');

str = replaced;

   d1 = str.substr(0,1);

   parseInt(d1);

if ( d1 > 0 ) {

d1 = d1 - 1;

}

d1 = d1 * 10;

d2 = str.substr(1,1) * 1;

d3 = str.substr(2,1) * 3;

d4 = str.substr(3,1) * 5;

d5 = str.substr(4,1) * 7;

d6 = str.substr(5,1) * 9;

d7 = str.substr(6,1) * 11;

d8 = str.substr(7,1) * 13;

d9 = str.substr(8,1) * 15;

d10 = str.substr(9,1) * 17;

d11 = str.substr(10,1) * 19;

tot = d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 + d11;

rem = tot % 89;

if ( rem === 0 ) {

ok = 'true';

}else {

ok = 'false';

}

Add custom headers in page

function onLoad() {
debugger;
getControl("Page1").addStyleClass("pagebackgroundimage");

var oPage = getControl("Page2");
oPage.setCustomHeader(new sap.m.Bar({
contentLeft: [new sap.m.Button({
id: "_logOffButton",
type: "Default",
press: "onLogoutButtonPress",
visible: false,
tooltip: "Log Out",
icon: "sap-icon://log"
}),
new sap.m.Button({
id: "_navButton",
type: "Back",
press: "backPressed",
visible: true
})
],
contentMiddle: [new sap.m.Label({
text: "Test",
id: "_page2_title"
})],
contentRight: [new sap.m.Image({
src: "/sap/bc/bsp/sap/ZIQX_DEMO_THEME/iqxlogo-300x179.png",
height: "40px"
}),
new sap.m.Label({
text: "Version 1.0",
id: "Versionid"
})
]
}));

}

Reading parameters from the URLSample URL 

http://fiori.iqxbusiness.com/sap/bc/ui5_ui5/iqx/fab2/index_latest.html?sap-ui-appcache=false&interactive2=true&showlogoff=true&UserReference=10#Form/CN_CAPEX

var UserReference = jQuery.sap.getUriParameters().get("UserReference");

or

//get URI parameters (used in stand-alone apps)

var params = thisFormsController.getOwnerComponent().getComponentData().startupParameters;

if (params.length > 0) {

     var userRef = decodeURIComponent(params.UserReference[0]);

}


Hide Back button on Review and Submit page

if (getField("CurrentStatus" == STATUS) {

    getControl("_view1–_navButton").setVisible(false);

}

Dynamically load 3rd party external lib from external

This helps loading external 3rd JS library when it is not available in FAB

try {
  dateFns.isToday(new Date());
} catch (err) {
  new Promise(function (fnResolve, fnReject) {
    jQuery.sap.includeScript(
      "https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js",
      "date_fns", fnResolve, fnReject);
  }).then(function () {
    console.log("date_fns js loaded!!!")
  });
}

/Since SAPUI5 version 1.58 onward, jQuery.sap.includeScript is deprecated, hence use the following instead:

//Load function includeScript from module sap/ui/dom/includeScript
var includeScript = sap.ui.require("sap/ui/dom/includeScript");
try {
  dateFns.isToday(new Date());
} catch (err) {
  new Promise(function(fnResolve, fnReject) {
    includeScript(
	  "https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js",
	  "datefns_js", fnResolve, fnReject);
	}).then(function() {
	     console.log("datefns_js is loaded!!!")
	});
}

In case FAB form having Chart Container, should load external JS libs using requireJS:

let loadLibPromise;

//if requireJS is loaded.
if (('require' in window)) {
	loadLibPromise = new Promise(function(resolve, reject) {
		requirejs.config({
			paths: {
				"mustache_js": "https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min",
				"date_fns": "https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min"
			}
		});
		resolve();
	});
} else {
	//Otherwise, load requireJS and carry on.
	loadLibPromise = new Promise(function(resolve, reject) {
		sap.ui.require(["sap/ui/thirdparty/require"], function() {
			requirejs.config({
				paths: {
					"mustache_js": "https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min",
					"date_fns": "https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min"
				}
			});
			resolve();
		});
	});
}

loadLibPromise.then(require(["mustache_js", "date_fns"], function(returnedFns1, returnedFns2) {
	console.log("mustache_js is loaded!")
	//assign loaded lib to global variable.
	window.Mustache = returnedFns1;
	window.dateFns = returnedFns2;
}));

In case of a JS library has a dependency, the following sample would help:

Load external JS library with dependencies
let loadLibPromise;
var formulajs; //Global variable
 
//if requireJS is loaded.
if (('require' in window)) {
  loadLibPromise = new Promise(function(resolve, reject) {
    requirejs.config({
      shim: {
        "formulajs": { deps: ['jStat'] }
      },
      paths: {
        "formulajs": "https://cdn.jsdelivr.net/gh/formulajs/formulajs@2.6.10/dist/formula.min",
        "jStat": "https://cdn.jsdelivr.net/npm/jstat@1.9.2/dist/jstat.min"
      }
    });
    resolve();
  });
} else {
  //Otherwise, load requireJS and carry on.
  loadLibPromise = new Promise(function(resolve, reject) {
    sap.ui.require(["sap/ui/thirdparty/require"], function() {
      requirejs.config({
        shim: {
          "formulajs": { deps: ['jStat'] }
        },
        paths: {
          "formulajs": "https://cdn.jsdelivr.net/gh/formulajs/formulajs@2.6.10/dist/formula.min",
          "jStat": "https://cdn.jsdelivr.net/npm/jstat@1.9.2/dist/jstat.min"
        }
      });
      resolve();
    });
  });
}
 
loadLibPromise.then(require(["formulajs"], function(returnedFns1) {
  console.log("formulajs is loaded!");
  formulajs = returnedFns1;
}));
Get user information from SCP FLP 
Get user information from SCP FLP
//Get User data logged into SCP FLP:
var oUserData = sap.ushell.Container.getUser();

//Get User ID in SCP: i.e: SAP S-ID  "s001276XXXX"
var vUsrID = oUserData.getId();

//Get User full name in SCP: i.e "Vu Nguyen"
var vFullName = oUserData.getFullName();

// Get user's email address in SCP: i.e "xxx@iqxbusiness.com"
var vEmail = oUserData.getEmail();
Get all the model data fields

Call the inbuilt function fabGetData() to fetch all the model data fields.

var getData = fabGetData();
Ternary Operator

Accepts 3 operands and acts as a shortcut to IF statements

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

Get the current page 

var currentPage = _fab.byId("_app").getCurrentPage().getId()

var currentPage = _fab.byId("_app").getCurrentPage().getId()


You can compare it with getControl("YourPageName").getId() to check if its the same page you are doing validations on.

Change the code while debugging to test

Add a line of code in the first script you use with the syntax //# sourceURL=some_name.js

Eg: //# sourceURL=journal_upload.js

This would open the journal_upload.js in runtime instead of the temporary application and enables the developer to change code on the fly to check while debugging.

NOTE: This line of code has to be deleted before it is moved to production, as it gives a developer the ability to change code in the run-time.

Resize Image

This JS snippet is to resize the image from the upload image file. On mobile, the UI5 Upload control will support the function to take a picture straight from the camera or pick up the photo from the library.

Resize Image
/* sample settings
let mySettings = {
    file: $image.files[0],
    maxSize: 500
};
*/

var resizeImage = function(settings) {
	var file = settings.file;
	var maxSize = settings.maxSize;
	var reader = new FileReader();
	var quality = 0.2; //From 0 to 1 only
	var image = new Image();
	var canvas = document.createElement('canvas');
	var dataURItoBlob = function(dataURI) {
		var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
			atob(dataURI.split(',')[1]) :
			unescape(dataURI.split(',')[1]);
		var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
		var max = bytes.length;
		var ia = new Uint8Array(max);
		for (var i = 0; i < max; i++)
			ia[i] = bytes.charCodeAt(i);
		return new Blob([ia], {
			type: mime
		});
	};
	var mimeType = function(dataURI){
	    return dataURI.split(',')[0].split(':')[1].split(';')[0];
	};
	var resize = function() {
		var width = image.width;
		var height = image.height;
		if (width > height) {
			if (width > maxSize) {
				height *= maxSize / width;
				width = maxSize;
			}
		} else {
			if (height > maxSize) {
				width *= maxSize / height;
				height = maxSize;
			}
		}
		canvas.width = width;
		canvas.height = height;
		canvas.getContext('2d').drawImage(image, 0, 0, width, height);
		return dataUrl = canvas.toDataURL('image/jpeg', quality);//(mimeType(image.src), quality); //('image/jpeg', 1.0);
	};
	return new Promise(function(ok, ko) {

	    var orientation;

		if (!file.type.match(/image.*/)) {
			ko(new Error("Not an image"));
			return;
		}
		reader.onload = function(readerEvent) {
			image.onload = function() {
				return ok(resize());
			};

			image.src = readerEvent.target.result;

		};
		reader.readAsDataURL(file);

	});
};

//Sample usage
//JS Function handle FileUpload contol's change event
function onFileUploadChange(evt) {

	let key = evt.getSource().data("key");
	let file = evt.getParameters("files").files[0];
	if (file !== undefined) {
		let fileType = file['type'];
		if (fileType.match(/^image\//)) {
			resizeImage(
				//This is the setting input for the resize function
				{
					file: file,    //input image file from the control.
					maxSize: 4032  //set a side of the max resolution output,
							       //the other side will be automatically rescaled.
				}
			).then(function(resizedImage) {
				//input resizedImage of this function is the image in base64.
				//carry on your logic after the image is resized.
				//savePhoto(newImage);
			}).catch(function(err) {
				fabAlert(err);
			});

		} else {
			fabAlert("Only attach a photo!");
		}
	}
}