Accessing Multi-row variables set client side in ServiceNow

Multi-row variable sets (MRVS) are a fairly recent addition to the Service Catalog in ServiceNow, having been introduced in the London release. Unlike a traditional variable set, which is a collection of singular variables, a MRVS allows the population of an arbitrary* number of rows of data, displayed in a table format, with a series of predefined field columns. Some field types, such as list collectors and macros, and other service catalog functionality (such as ‘Map to field’) are not available from a MRVS. See the official documentation for more details: Service Catalog Variable Sets

When implementing a MRVS, you may wish to be able to dynamically access the values entered into the table. This can be accomplished via client-side scripting. In the example below, our hypothetical requirement is to calculate a sum of decimal values stored in separate rows of the set. We’ll accomplish this by using a macro variable, which will input the total value of the desired column into a field of our choosing.

We start by creating a script that can be accessed via a UI element, such as from a UI macro or Service Portal widget. This script will be an onLoad catalog client script in this case. By loading this script with the form, we give the macro an on-click function in order to do the calculation when the button is pressed.

 

function onLoad() {
	//onLoad function can be empty. We will define our function outside of the onLoad context to put it in a scope reachable by the macro button.
}
function calcTotal() {
	var mrvs = g_form.getValue("IO:46c07bd31b25041064d6337bcd4bcb26"); //We can access the MRVS values via getValue, using the "IO:" prefix, followed by the MRVS sys_id
	var objList = JSON.parse(mrvs); //The MRVS values are captured as a JSON string, which we parse, creating an array
	var calculatedAmount = 0;
	var tax = parseFloat(g_form.getValue('u_tax'));
	var freight = parseFloat(g_form.getValue('u_freight'));
	for (var i = 0; i < objList.length; i++) { //Iterate through array to sum values
		calculatedAmount += parseFloat(objList[i].dollar_amount);
	}
	var taxTotal = tax * calculatedAmount;
	var rawTotal = calculatedAmount + taxTotal + freight;
	var finalTotal = rawTotal.toFixed(2);
	g_form.setValue('u_invoice_total', finalTotal);
}

 

You can now evoke the calcTotal() function from a UI macro (made with Jelly Script, for use on the classic Service Catalog view) or from a widget on the Service Portal.

The final result should look something like this:

*Baseline, you are restricted to a maximum of 50 rows in a MRVS