We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

Anish Reghu
Kilo Sage

CODES BELOW ARE PICKED UP FROM MULTIPLE SOURCES IN THE COMMUNITY, SOME ARE SELF IMAGINED SCENARIOS AND TESTED. USE THEM IN YOUR CONTEXT ACCORDINGLY.

CLIENT SCRIPT - Get Row count of Multi row variable set or to validate by row count.

function onSubmit() 
{
    //get the MRVS
    var multiRowVariableSet = JSON.parse(g_form.getValue('<VARIABLE_SET_NAME>'));

    //Get number of rows
    var numberOfRows = multiRowVariableSet.length;

    //If lower then 5 abort and show message
    if (numberOfRows < 5) {
        g_form.addErrorMessage('<CUSTOM_ERROR_MESSAGE>');
        return false;
    }

}

 

BACKGROUND SCRIPT - to concatenate and store in the same String field.

var gr = new GlideRecord('<TABLE_NAME>');
gr.addQuery('<FIELD_NAME>',"<FIELD_VALUE>");
gr.query();

while(gr._next())
{
gr.<TARGET_FIELD> += " " + gr.<INPUT_FIELD>;
gr.update();

}

//Replace: 
//<TABLE_NAME> - with the table you are querying;
//<FIELD_NAME> and <FIELD_VALUE> to filter your search.
//We are doing A = A+B here.
//<TARGET_FIELD> - Input A and also the output field.
//<INPUT_FIELD> - the input B in this case.
//<TARGET_FIELD> and <INPUT_FIELD> should be String.

 

Send notification to users in incident, when Problem record Closed or (any state change)

Event:

Event name - incident.problem_closed

Table name - incident

Fired by - BR on problem table when Problem is closed.

Description - Notify Incident owner.

find_real_file.png

Configure when and whom to send the notification - Here is where you tell the notification that your recipients are in the event parameters.

find_real_file.png

//BUSINESS RULE - AFTER - Condition - State changes to Closed.

(function executeRule(current, previous /*null when async*/) {

//Declare the arrays where you need to store the recipients 
//Array because more than 1 user.

var incidentOwners = [];
var incidentAssignee = [];

//Query the incident table to fetch the recipients.

var incidentGR = new GlideRecord("incident");

// problem_id - FIELD ON INCIDENT TABLE.
//current.sys_id - REFERRING TO PROBLEM RECORD SYS ID.
//'current' is PROBLEM BECAUSE BR IS DEFINED ON PROBLEM TABLE.


incidentGR.addQuery("problem_id", current.sys_id);
incidentGR.addActiveQuery();

//DEFINE YOUR OWN QUERY FOLLOWING THE SYNTAX ABOVE.

//DON'T FORGET THIS, OR ELSE IT IS LIKE NOT PRESSING THE
//'RUN' BUTTON AFTER SETTING THE SOFT FILTER.

incidentGR.query();

//YOUR QUERY FETCHED RESULTS.
//NOW ACCESS THEM USING THE next() method.

//USE THE push() METHOD TO PUSH THE DATA INTO THE ARRAY.
//SERVICENOW RETURNS SYS_ID - THE DATABASE VALUE FOR ANY RECORD.
//HENCE WE USE METHODS LIKE getValue() TO RETRIEVE THE USER DEFINED NAMES OF THAT RECORD.

while (incidentGR.next()) 
{
incidentAssignee.push(incidentGR.getValue('assigned_to'));
incidentOwners.push(incidentGR.getValue('caller_id'));
}

//USING THE LENGTH VARIABLE OF THE ARRAY WE ASSESS WHETHER THE ARRAY HAS ELEMENTS IN IT.
//IF YES, TRIGGER THE EVENT USING gs.eventQueue() METHOD.

if (incidentOwners.length >0 || incidentAssignee.length >0)
gs.eventQueue('incident.problem_close', current, incidentAssignee.toString(), incidentOwners.toString(), '');

})(current, previous);

 

BUSINESS RULE: To update Problem ticket when 'Problem' reference field (OOTB) is FILLED, EMPTIED, CHANGED on an incident.

BEFORE BUSINESS RULE - UPDATE.

CONDITION BUILDER - Problem Changes.

CONDITION - EMPTY

(function executeRule(current, previous /*null when async*/ ) {

    // Add your code here
    var gr = new GlideRecord('problem');
    var newNum, oldNum;
    
	//VARIABLES TO STORE NEW AND OLD problem_id FIELD VALUES.
	//OR ELSE WE WILL HAVE TO QUERY DISPLAY VALUE EVERY TIME, WE NEED IT.
    newNum = current.problem_id.getDisplayValue();
    oldNum = previous.problem_id.getDisplayValue();
    
	//DEFINING STRING VARIABLES AND STORING MESSAGE TO BE PASSED ON WORK NOTES OR LOGS.
    var data = "Incident " + current.number + " is now linked to the problem ticket " + newNum + "."; //linked
    var remData = "Incident " + current.number + " is NO MORE LINKED to the problem ticket" + oldNum; //removed
    var newData = "Incident " + current.number + " is NEWLY LINKED to the problem ticket " + newNum + " from " + oldNum; //Changed
	
	//Below IF-ELSE-IF validation is to check which input to query with.
	// Use newNum if Problem field is filled in,
	//Else use oldNum if field is emptied.

    if ((newNum != "") || (newNum != "" && oldNum != ""))
        gr.query('gr.number', newNum);
    else if (newNum == "" && oldNum != "")
        gr.query('gr.number', oldNum);


    while (gr.next()) {
		
        if (gr.number == (oldNum || newNum)) 
		{                
			//If you put a log inside this loop, if the above IF validation is not done, 
			// the log will be generated for every record while loop passes through.

            if ((previous.problem_id == "") && (current.problem_id != ""))               //SCENARIO 1
			{
                gr.work_notes = data;
                gr.update();

            } 
			else if ((current.problem_id == "") && (previous.problem_id != ""))          //SCENARIO 2
			{
                gr.work_notes = remData;
                gr.update();
            } 
			else if ((current.problem_id != "") && (previous.problem_id != ""))          //SCENARIO 3
			{
                gr.work_notes = newData;
                gr.update();
            }

        }
    }

})(current, previous);

 

FUNCTIONAL CASE:

** User inputs caller_id on the incident form - reference field - sys_user.

** Query the cmn_location table for Location name and fetch that string.

** Using the string, query the user group table to fetch a matching group record.

** If multiple groups are listed, fetch the recently created record ordered by Created by.

Solution:

Client Script and Script include used.

/***********CLIENT SCRIPT************/

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
   if (isLoading || newValue === '') {
      return;
   }
	
	var name = g_form.getValue('caller_id');
	
	var ga = new GlideAjax('CSTM_GroupName');        //Replace with Script Include name
	ga.addParam('sysparm_name','fetchGrpName');      //Param 1 - Script include Method
	ga.addParam('sysparm_caller_id',name);           //Param2 - Parameter to pass to Script include from Client script
	ga.getXML(getResponse);
	
	function getResponse(response) {
	var answer = response.responseXML.documentElement.getAttribute("answer");
	//alert(answer);
	g_form.setValue('assignment_group',answer);
}

 

/****************SCRIPT INCLUDE - CLIENT CALLABLE - TRUE**************/

var CSTM_GroupName = Class.create();
CSTM_GroupName.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	fetchGrpName : function() {
	
        //Fetch the Parameter from CS	
	var pm = this.getParameter('sysparm_caller_id');
	
        //Defined a variable to store location name.
	var locName;

        /******QUERY User Record and Search for the user passed from CS*****/
	var usrGr = new GlideRecord('sys_user');
	usrGr.addQuery('sys_id',pm);
	usrGr.query();
	
        /*******DOT WALK AND STORE LOCATION 'STRING VALUE' IN THE VARIABLE*****/	
	if(usrGr.next())
	{
          locName = usrGr.location.getDisplayValue();
	  gs.log("ANI location"+locName);
	}
		
		
	/**********UNTIL NOW FETCHED THE LOCATION - AS A STRING**********/
		
        /**********FURTHER IN GROUP TABLE ********/
        /*******QUERY - FOR RECORD THAT CONTAINS LOCATION STRING*****/

	var gr = new GlideRecord('sys_user_group');
	gr.addQuery('name', 'CONTAINS', locName);
	gr.query();
	gr.setLimit(1);
	
	/***********IF RECORD EXISTS - RETURN THE GROUP NAME**************/
	if(gr.next())
		var ans = gr.name;
		//gs.log("ANISH:"+ ans);
		return ans;
		
		
	},
	
//NOTE - THIS WILL ONLY RETRIEVE THE LATEST (CREATED) GROUP AND ASSIGN IT TO THE ASSIGNMENT GROUP FIELD ON THE INCIDENT.


    type: 'CSTM_GroupName'
});

 

MORE USE CASES COMING UP ...

 

Let's build a beautiful repository of codes.

 

Cheers and Happy coding,

Anish

Version history
Last update:
‎10-28-2020 11:48 PM
Updated by: