How to achieve the list collector values to clear the values of its reference

Exp1Gr
Mega Contributor

Hi can one guide me or Implemented below requirment

I have a catalog item with two list collector variables. The second variable should display values based on the selections made in the first variable. When multiple options are selected in the first variable, the corresponding reference values are available in the second variable for selection.

I wrote an onChange client script to clear values in the second variable when a choice is deselected from the first variable. However, the current script clears all values in the second variable. The requirement is to clear only the values that belong to the deselected choice, while keeping the others intact.

Looking for insights or suggestions on how to adjust the script to achieve this.

GunduSrikan_0-1755848394207.png

 

Thanks in advance!

9 REPLIES 9

RaghavSh
Kilo Patron

Can you share the script?


Raghav
MVP 2023

Rafael Batistot
Kilo Patron

Hi @Exp1Gr 

 

May you follow those steps 

  • Store a mapping of first variable options to second variable options (can be in a Script Include or object in client script).
  • On change of the first list collector:
    • Determine which options were deselected.
    • Remove only the corresponding items from the second list collector.
    • Keep items that are still valid.

 

(function execute(current, g_form, g_user, g_scratchpad) {

// Get the current and previous selections
var firstVarSelected = g_form.getValue('first_variable'); // comma-separated sys_ids
var secondVarSelected = g_form.getValue('second_variable'); // comma-separated sys_ids

// Map first variable options to second variable options
var mapping = {
'option1_sysid': ['optionA_sysid', 'optionB_sysid'],
'option2_sysid': ['optionC_sysid', 'optionD_sysid'],
'option3_sysid': ['optionE_sysid']
};

// Convert selections to arrays
var firstSelectedArr = firstVarSelected ? firstVarSelected.split(',') : [];
var secondSelectedArr = secondVarSelected ? secondVarSelected.split(',') : [];

// Determine which second variable values should remain
var validSecondValues = [];
for (var i = 0; i < firstSelectedArr.length; i++) {
var key = firstSelectedArr[i];
if (mapping[key]) {
validSecondValues = validSecondValues.concat(mapping[key]);
}
}

// Filter second variable to keep only valid items
var newSecondValues = [];
for (var j = 0; j < secondSelectedArr.length; j++) {
if (validSecondValues.indexOf(secondSelectedArr[j]) > -1) {
newSecondValues.push(secondSelectedArr[j]);
}
}

// Set the filtered values back
g_form.setValue('second_variable', newSecondValues.join(','));

})(current, g_form, g_user, g_scratchpad);

 

 

Explanation

  • mapping is where you define which options in first list collector correspond to options in second list collector.
  • Only items still valid after deselection are kept.
  • This script ensures the second list collector dynamically adjusts without removing unrelated selections.

 

Hi @Exp1Gr ,

 

Store the mapping of Process → Functions

There are a few options you can store the mapping 

If it’s static, create a JSON object in your script.

If it’s dynamic (process–function relationship in a table), create a lookup table in ServiceNow (e.g., u_process_function_mapping with process and function fields). Then fetch data with GlideAjax.

2. Client Script (onChange of Which Process)

Here’s a sample for your exact variables:

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;

var selectedProcesses = g_form.getValue('which_process').split(',').filter(Boolean);
var previousProcesses = oldValue.split(',').filter(Boolean);
var selectedFunctions = g_form.getValue('what_function').split(',').filter(Boolean);

// Find deselected processes
var removedProcesses = previousProcesses.filter(function(proc) {
return selectedProcesses.indexOf(proc) === -1;
});

if (removedProcesses.length === 0) return;

// Example mapping (replace with GlideAjax if dynamic)
var processFunctionMap = {
"process_sysid_1": ["function_sysid_1", "function_sysid_2"],
"process_sysid_2": ["function_sysid_3"],
"process_sysid_3": ["function_sysid_4", "function_sysid_5"]
};

// Remove only functions belonging to removed processes
removedProcesses.forEach(function(proc) {
if (processFunctionMap[proc]) {
selectedFunctions = selectedFunctions.filter(function(func) {
return processFunctionMap[proc].indexOf(func) === -1;
});
}
});

// Set filtered functions back
g_form.setValue('what_function', selectedFunctions.join(','));
}

 

Mark it helpful if this helps you to understand. Accept solution if this give you the answer you're looking for
Kind Regards,
Pavani P

Ashish Parab
Mega Sage

Hello @Exp1Gr,

 

I believe you created a script include to add values to the 'What function' variable. How are you calling that script include? Are you using an onChange client script? Please share the script you created.

 

Please mark my response as Correct and Helpful if it assists you.


Thanks,
Ashish Parab