Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Set Variable Editor Read Only

Guilherme Popo2
Tera Contributor

Good afternoon Guys, could you help me?

 

I have a request to make the fields in the Variable Editor Read Only, however, some fields have the information "resolver_form" in a custom field and should not be mandatory.

 

I created the following client script that validates whether the custom field called u_csc_class has the value "resolver_form", so the fields that do not have this information should be blocked, however, this is not working, it is still leaving all the fields editable.

 

function onLoad() {
    //Type appropriate comment here, and begin script below

    var getTicketState = g_form.getValue('state');
    var getItem = g_form.getVlaue('u_item');

    if (getTicketState != '-20') {
        var fields = g_form.getEditableFields();
        alert(fields);
        for (var x = 0; x < fields.length; x++) {

            var ga = new GlideAjax('SNUtilsCSCLatam');
            ga.addParam('sysparm_name', 'getVariableClass');
            ga.addParam('catalog_item_sys_id', getItem);
            ga.addParam('sysparm_variable_name', fields);

            ga.getXMLAnswer(function(response) {
                var getVariableClass = response;
                if (getVariableClass != 'resolver_form') {
                    g_form.setReadOnly(fields[x], true);
                }
            });

        }
    }
}

The include script that I am using accesses the item_option_new table and searches for the item and the variable and returns the information present in the u_csc_class field:

 

getVariableClass: function() {

        var catalogItemSysId = this.getParameter('catalog_item_sys_id');
        var variableName = this.getParameter('variable_name');
        var gr = new GlideRecord('item_option_new');
        gr.addQuery('cat_item.sys_id', catalogItemSysId);
        gr.addQuery('name', variableName);
        gr.query();


        if (gr.next()) {
            return gr.getValue('u_csc_class');
        }
        return '';

    },

 

1 REPLY 1

-O-
Kilo Patron

There are multiple problems with your scripts:

  • calling client side in a loop - performance issue
  • calling client side with the entire list of variables as parameter on each loop:
    ga.addParam('sysparm_variable_name', fields);
    but treating it as a single field in the Script Include:
    var variableName = this.getParameter('variable_name');
    ...
    gr.addQuery('name', variableName);
    ...
    if (gr.next()) {
    	...
  • while at it, it seems you are using one name client side and a different name server side for the same thing:
    client side:
    ga.addParam('sysparm_variable_name', fields);
    server side:
    var variableName = this.getParameter('variable_name');
  • you are using parameter name that doesn't start with prefix sysparm_:
    ga.addParam('catalog_item_sys_id', getItem);
    Best would be to fetch all the variable names, make a list of those, send in the list and receive back an array of objects that have two properties: the name of the variable and whether it should be read-only or not.
    Also I would not rely on a solution that user the
    g_form.getEditableFields();
    API - it might not be available in all UIs/Environments. You could just send in the Catalog Item ID and load the list of variables and the flag and set fields to read-only where needed.

The Client Script could look like:

function onLoad() {
	var getTicketState = g_form.getValue('state');
	var getItem = g_form.getVlaue('u_item');

	if (getTicketState != '-20') {
		var ga = new GlideAjax('SNUtilsCSCLatam');

		ga.addParam('sysparm_name', 'getVariableClass');
		ga.addParam('sysparm_catalog_item_sys_id', getItem);

		ga.getXMLAnswer(updateVariableReadOnlyFlag);
	}

	function setReadOnly(variableFlag) {
		if (variableFlag.readOnly && !g_form.isReadOnly(variableFlag.name))
			g_form.setReadOnly(variableFlag.name, true);
		return variableFlag;
	}

	function updateVariableReadOnlyFlag(response) {
		var variableFlags = parse(response);
		return variableFlags.map(setReadOnly);
	}

	function parse(json) {
		try {
			var data = JSON.parse(json);
			return Array.isArray(data) ? data : [];
		}
		catch (ex) {
			console.log(ex);
			return [];
		}
	}
}

and the client callable Server Script could look like:

var SNUtilsCSCLatam = Class.create();

SNUtilsCSCLatam.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {

	'getVariableClass': function () {
		var fieldReadOnlyFlags = [];
		var catalogItemSysId = this.getParameter('sysparm_catalog_item_sys_id');
		var gr = new GlideRecord('item_option_new');

		gr.query('cat_item', catalogItemSysId);

		while (gr._next())
			fieldReadOnlyFlags.push({
				'name': '' + gr.name,
				// Assuming u_csc_class has type True/False
				'readOnly': global.JSUtil.getBooleanValue(gr, u_csc_class),
			});

		return JSON.stringify(fieldReadOnlyFlags);
	},

	'type': 'SNUtilsCSCLatam',

});

 

B.t.w. don't call variables fields - those are two very well defined different things; mixing those just confuses people.
Also remove unnecessary, useless comments like

// Type appropriate comment here, and begin script below

from your script - it would show that you actually care about quality.