Scripting with a Multi Row Variable Set - and a Possible Reporting Workaround
When you add a multi row variable set (MRVS) to a catalog item, you may be asked to add some validation before the request or task is submitted/updated, do something with those values in the workflow, and/or show the values in a report. As of Orlando, MRVS variables cannot be shown in reports, but skip to the end for a potential workaround that may work for some use cases.
My initial requirement started off easy enough. There was an existing request to order network gear, in multiple quantity, so they needed a way to enter multiple serial numbers once the devices were received. Previous to the MRVS being available, I queried the related Affected CIs to be sure serial numbers had been added to each before a certain task could be closed.
The new way - a MRVS with one variable.
The first requirement after delivering the MRVS was to make sure the number of serial numbers added in the MRVS was equal to the quantity received variable, before the task could be Closed Complete. If you just need to make the MRVS mandatory, add something like this to your onSubmit catalog client script:
if(g_form.getValue('serial_number') == []){ //name of the MRVS alert('You must enter at least 1 Serial Number!'); return false; }
To make sure the number of MRVS rows matches the quantity of units received, I added this to an onSubmit catalog client script:
var snlist = g_form.getValue('serial_number'); // name of the MRVSvar obj = JSON.parse(snlist);var length = obj.length;var qty = g_form.getValue('v_qty_received');if(snlist == ''){ // no rows were added to the MRVS g_form.addErrorMessage('The number of serial numbers entered must match the quantity.'); return false;}else if(length != qty){ g_form.addErrorMessage('The number of serial numbers entered must match the quantity.'); return false; }
A final (for now?) requirement on the client side - before this task can be closed, make sure none of the serial numbers are duplicated - with each other, or with those of existing network devices. This one turned out to be a bit trickier since I was getting the sysid of the variable in the MRVS returned in the JSON, so first I had to replace the sysid with something useful like the variable name:
snlist = snlist.toString().replace(/305886aadbb977807601d3eb5e961932/g,'v_serial_number_mrvs');
Then I passed this JSON formatted string to a script include to first parse the string into a JSON object, then check the array to make sure the same serial number wasn't entered more than once (it has happened):
var obj = JSON.parse(snlist);var sorted_arr = obj.slice().sort();for (var k = 0; k < sorted_arr.length - 1; k++) { if (sorted_arr[k + 1].v_serial_number_mrvs == sorted_arr[k].v_serial_number_mrvs) { answer = 'Serial number ' + sorted_arr[k].v_serial_number_mrvs + ' is duplicated on the table of serial numbers. Edit or remove one of the entries.'; return answer; }}
Finally, looping through the array to query the netgear table for an existing serial number:
https://www.servicenow.com/community/itsm-articles/scripting-with-a-multi-row-variable-set-and-a-possible-reporting/ta-p/2300082