Need help: Update a Read-only variable with approvers data on variables value change in catalog item

MHimabindu
Tera Contributor

Hello Community,

 

I am working on catalog item and need some help with a development requirement.

 

Use case: I have around 32 variables in my catalog item. Each of these variable is user-selectable(list collector). Based on variable value empty/filled, I want to dynamically update a read-only variable depending on the non-empty variables. This update needs to happen in real-time on the client side before form submission.

 

I have tried the classic approach with  onChange catalog client scripts on each variable, but this might cause performance issue and is inefficient.

 

I am looking for a better and single script to listen for changes on any variable and updates the read-only variable accordingly.

 

Any help or suggestions are greatly appreciated!!

 

Thanks in advance!!

9 REPLIES 9

Hi @Rafael Batistot 

 

Thanks for response,PFB modified script but not able to get expected output(no alerts as well). I am not sure if I am missing something here..

 

function onLoad() {
var variableNames = ['var1, 'var2', 'var3', '........,'var32'];
 
var amt = g_form.getValue('varA');
var ct = g_form.getValue('varB');
var fml = g_form.getValue('varC');
 
var finalAppMat = [];
 
function updateSummary() {
       var app = [];
 
       variableNames.forEach(function(name) {
            var val = g_form.getValue(name);
            if (val) {
               app.push(name);
            }
         });
         
      if (app.indexOf('var1') != -1)
                    app.push("Optional App");
 
      if (fml == 'test') {
          if ((ct == 'grp') || (cat == 'gp')) {
              if (app.indexOf('var2') != -1)
                   app.push("Global App");
              if (app.indexOf('var3') != -1)
                   app.push("Additional Global App");
                    }
                  }
                           
      var Matrix = "Order of matrix :\n\n";

        if (finalAppMat.length != 0) {
            for (i = 0; i < app.length; i++) {
                Matrix = Matrix + "App" + (i + 1) + " : " +finalAppMat[i] + "\n";
            }
        }
          g_form.setValue('Read-Only Varibale', Matrix);
    }

    // Attach a single event listener to each variable dynamically
    variableNames.forEach(function(name) {
        g_form.attachChangeHandler(name, function() {
            updateSummary();
        });
    });

    // Initial update on load
    updateSummary();
}
 
 
 
Thanks!
 
 

Can you try with below script:

function onLoad() {
var variableNames = ['var1', 'var2', 'var3', /* ..., */ 'var32'];

function updateSummary() {
var amt = g_form.getValue('varA');
var ct = g_form.getValue('varB');
var fml = g_form.getValue('varC');

var app = [];

// Collect all checked or filled-in variables
variableNames.forEach(function(name) {
var val = g_form.getValue(name);
if (val) {
app.push(name);
}
});

// Add extra labels if certain conditions are met
if (app.indexOf('var1') !== -1)
app.push("Optional App");

if (fml === 'test' && (ct === 'grp' || ct === 'gp')) {
if (app.indexOf('var2') !== -1)
app.push("Global App");
if (app.indexOf('var3') !== -1)
app.push("Additional Global App");
}

// Build the matrix string
var matrix = "Order of matrix:\n\n";
for (var i = 0; i < app.length; i++) {
matrix += "App " + (i + 1) + " : " + app[i] + "\n";
}

// Set the read-only variable
g_form.setValue('read_only_variable', matrix); // Make sure variable name is lowercase and correct
}

// Run updateSummary on load
updateSummary();

// Run updateSummary whenever any of the 32 variables change
variableNames.forEach(function(name) {
g_form.setOnChange(name, function() {
updateSummary();
});
});

// Also listen to controlling variables (if they change)
['varA', 'varB', 'varC'].forEach(function(name) {
g_form.setOnChange(name, function() {
updateSummary();
});
});
}

 

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

Hi @pavani_paluri 

 

Updated accordingly, no change on the read-only field..

 

I have added alerts to check for any breaks in the script but no use.

 

Thanks!

@pavani_paluri 

the code you shared is a tested one?

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Hi, @MHimabindu 

 

i did some changes, let me know if work now 

 

var variableNames = ['var1', 'var2', 'var3', ..., 'var32']; // Replace with actual variable names
var readOnlyVariableName = 'read_only_variable'; // Replace with your read-only variable name

function updateSummary() {
var selectedApps = [];
var summaryText = "Order of matrix:\n\n";

// Get values from other control variables
var amt = g_form.getValue('varA');
var ct = g_form.getValue('varB');
var fml = g_form.getValue('varC');

// Check which variables are filled
variableNames.forEach(function(name) {
var val = g_form.getValue(name);
if (val) {
selectedApps.push(name); // or g_form.getDisplayValue(name) if you want labels
}
});

// Add custom logic based on selections
if (selectedApps.indexOf('var1') !== -1) {
selectedApps.push("Optional App");
}

if (fml === 'test') {
if (ct === 'grp' || ct === 'gp') {
if (selectedApps.indexOf('var2') !== -1) selectedApps.push("Global App");
if (selectedApps.indexOf('var3') !== -1) selectedApps.push("Additional Global App");
}
}

// Build the matrix text
for (var i = 0; i < selectedApps.length; i++) {
summaryText += "App" + (i + 1) + ": " + selectedApps[i] + "\n";
}

// Set the read-only variable
g_form.setValue(readOnlyVariableName, summaryText);
}

// Attach onChange listeners dynamically
variableNames.forEach(function(name) {
g_form.onChange(name, updateSummary);
});

// Initial run on form load
updateSummary();

 

 

***Use g_form.getDisplayValue(name) if you want to display labels instead of internal values.

 

Ensure “read_only_variable” exists and is set to read-only.

Add this as a Catalog Client Script, type onLoad, and set “Applies to” = “Catalog Item”.


If you’re using List Collector variables, this still works, but for multi-selects, you may want to split values and loop through them.

 

If you found this response helpful, please mark it as Helpful. If it fully answered your question, consider marking it as Correct. Doing so helps other users find accurate and useful information more easily.