petercawdron
Kilo Guru

You can use g_form.setValue to set values in a multi-row variable set by passing an array that contains key/value pairs that reflect your multi-row variable set variables. For example, here's a multi-row variable set called travellers that has variables traveller, mobile_phone, additional_information

g_form.setValue('travellers',[{"additional_information":"","mobile_phone":"12345","traveller":"Peter"}]);

The challenge comes if you have any variables that use a reference field. As you can only pass one string for each variable, either the value (sys_id) or the display value (in this case, "Peter"). The problem is... 

  • If you pass the sys_id then the sys_id will appear on the screen (not good) but when you edit the line, it'll resolve to the display value
  • If you pass the display value, then it appears on the screen okay, but if you edit the line it won't resolve at all

Others may have simpler ways to do this, but I used a bit of angular magic and set the display value normally (just like in the example above), while using angular to set the sys_id in the background.

NOTE: This is the onLoad script for the multi-row variable set, not the catalog item itself

function onLoad() {

	var multiRowVariableSetName = 'travellers';

	//get the window object by stealth
	var myWindow = (0,eval)('this');

	//get the service portal angular object already loaded into memory (instead of making an ajax call). 
	var ngScope = myWindow.angular.element(myWindow.document).scope();
	var ngMain  = myWindow.angular.element('main');

	//find the variable set by name (MUST be unique)
	var findMRVS = ngMain.injector().get('$filter')('filter')(ngMain.scope().containers,{$:multiRowVariableSetName});

	//set up an object pointing at the multi-row variable set scope data 
	var thisMRVS = findMRVS[0].rows[0].columns[0].widgets[0].widget.data.sc_cat_item._fields[multiRowVariableSetName];

	//these names must match the names of variables in the variable set
	var thisValue  = [{"additional_information":"","mobile_phone":ngScope.user.mobile_phone,"traveller":ngScope.user.sys_id}];
	
	//First, use a regular setValue (but this won't set the sys_id)
	g_form.setValue('travellers',[{"additional_information":"","mobile_phone":ngScope.user.mobile_phone,"traveller":ngScope.user.name}]);

	//Second, set the sys_ids
	thisMRVS.value        = JSON.stringify(thisValue);
	thisMRVS.stagedValue  = JSON.stringify(thisValue);

	//Optional: Write the angular object for this multi-row variable set to the console log 
	//console.log(thisMRVS);
	//console.log(ngScope);
}

As with anything bespoke like this, YMMV, but for me this worked really well.

If you look at the angular object (thisMRVS) you'll see there settings like max_rows_size which can (probably) be used to restrict how many rows someone can enter.

To adapt this to work with your variable set, you'll need to alter the values of the variables multiRowVariableSetName and thisValue so they reflect your multi-row variable set.

Have fun

Comments
petercawdron
Kilo Guru

You can also use this to set policies from within a multi-row variable set... for example, if a value is entered on the multi-row variable set, but you need to change elements that are visible on the catalog item itself, you can use this in an onChange script for the multi-row variable set...

if(newValueDate < earlyDeparture){

	//This variable is NOT in the mult-row variable set, but we want to influence it
	var variableName = 'justification';

	//get the window object by stealth
	var myWindow = (0,eval)('this');

	var ngMain  = myWindow.angular.element('main');

	//find the variable by name (MUST be unique)
	var findVariable = ngMain.injector().get('$filter')('filter')(ngMain.scope().containers,{$:variableName});

	//set up an object pointing at the variable's angular scope data 
	var thisVariable = findVariable[0].rows[0].columns[0].widgets[0].widget.data.sc_cat_item._fields[variableName];

	thisVariable._visible      = true;
	thisVariable._mandatory    = true;
}

In this example, a field on the main catalog item is made visible and mandatory

petercawdron
Kilo Guru

If you want to change a value on the main catalog item in response to values changing on your multi-row variable set, use a little jQuery...

var myWin = (0,eval)(this);
if(myWin.jQuery('#sp_formfield_chkbox_important').hasClass('ng-empty')){
   myWin.jQuery('#sp_formfield_chkbox_important').trigger( 'click' );
}

This example is from an onChange client catalog script within the multi-row variable set, and sets a checkbox call chkbox_important on the main catalog item form.

chandrashobana
Giga Expert

@Peter Cawdron I am using this multi row variable set in a catalog form and this catalog item form is using in the order guide bundle. For each bundle included this item, i want to pre define the multi row variables values .(file share and access type)

Is it possible? Based on the number of file share , number of RITM's to be created.

 need urgent solution.

Version history
Last update:
‎05-15-2019 08:40 PM
Updated by: