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