Override Variable Set Default Value in Catalog Item

jmiskey
Kilo Sage

We use the Service Portal quite heavily.  We have a lot of Catalog Items on it.  For efficiency sake, we have a Variable Set that we use in the majority of our Catalog Items that returns a bunch of information about the Requestor and their Manager.  In this variable set, the "requested_for" field has the default value of:

javascript: gs.getUserID();

so it defaults to the person filling out the sheet , and then there are Catalog Client Scripts to populate all the related information about the user and their manager.

We have a "New Hire Onboarding" form that uses this Variable Set, but the issue is that a user would NEVER be filling out their own "New Hire Onboarding" form (as matter as fact, I need to ensure that the requestor CANNOT choose themself, which I can do with some Catalog Client Scripts).

So, what I really want to do is to "override" the default in the Variable Set.  But here is the tricky part -- I need to do this without making any changes to the Variable Set (under strict order from boss not to mess with that).  So, I need to do it using Catalog Client Scripts from the "New Hire Onboarding" Catalog Item.  

I was able to add code to clear the "requested_for" value, but it appears that runs AFTER the default is applied, so it left all the related User and Manager information populated, even though the "requested_for" value was cleared.  I think what I need to figure out is how to override the "default", so it is never applied in the first place, so those other related fields do not get an initial population based on the default value.

Does anyone have any good ideas on how to best accomplish this (without trying to write a whole bunch of code to undo everything)?

Thanks

 

10 REPLIES 10

Hmmm could you share how the catalog client scripts are setup in the variable set (or if all the same technique, just one?).

As you can see, my example does work. In our case: Requested for has a default value, and email / phone / location have a onChange Client Script (against requested for), which fills these fields.
Though, because I'm overwriting the requested for, email / phone / location are triggered again due to the onChange, and therefor made blanc.

Performance wise not really nice. Though, you don't have to alter the variable set.

Thinking about this while typing... could it be that your variables in the variable set have a onChange client script, but with a check (return) that the newValue should not be empty? And therefor the onChange is not triggered?

If my answer helped you in any way, please then mark it as helpful.

Kind regards,
Mark

---

LinkedIn

 

Kind regards,

 

Mark Roethof

Independent ServiceNow Consultant

10x ServiceNow MVP

---

 

~444 Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

LinkedIn

So, here is one of the Catalog Client Scripts on the Variable Set (the one that populates the related User information):

find_real_file.png

Here is the code:

function onChange(control, oldValue, newValue, isLoading) {
	if (newValue == '') {
		g_form.setValue('phone', '');
		g_form.setValue('site', '');

		//return;
	}else{

		var reqFor = g_form.getValue('requested_for'); //get value of the person requested for

		//get basic user info/

		var ajax = new GlideAjax('global.getUserInformation');  
		ajax.addParam('sysparm_name', 'getBasicUserInfo');  
		ajax.addParam('sysparm_usr', reqFor);
		ajax.getXML(returnInfo);
	}

	function returnInfo(serverResponse){  

		// get result element and attributes
		var result = serverResponse.responseXML.getElementsByTagName("result");
		var message = result[0].getAttribute("message");

		//check for message attribute and alert user
		// if(message) alert(message);

		//build output to display on client for testing 
		var output = "";

		// get favorite elements 
		var information = serverResponse.responseXML.getElementsByTagName("information");
		for(var i = 0; i < information.length; i ++) { 
			var name = information[i].getAttribute("name");

			var value = information[i].getAttribute("value");

			if (name == "phone"){
				g_form.setValue('phone', value);
			}
			else if (name == "manager"){
				g_form.setValue('manager', value);
			}
			else if (name == "site"){
				g_form.setValue('site', value);
			}
			else if (name == "title"){
				g_form.setValue('job_title', value);
			}
			else if (name == "department"){
				g_form.setValue('department', value);
			}


			//set read-only on variables
			g_form.setReadOnly('department', true);
			g_form.setReadOnly('job_title', true);
			g_form.setReadOnly('phone', true);
			g_form.setReadOnly('site', true);

			//alert(output); 
		}
	}
}

Here is the Script Includes that it calls:

var getUserInformation = Class.create();
getUserInformation.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	getBasicUserInfo: function(){  

		var user = this.getParameter('sysparm_usr'); //Get User from Client Script
		var result = this.newItem('result');

		var gr = new GlideRecord('sys_user'); //query user table
		gr.addQuery('sys_id', user);
		gr.query();

		if (gr.next()){
			var phone = gr.phone;
			var title = gr.title;
			var site = gr.location.getDisplayValue();
			var hire = gr.u_hire_date;
			var department = gr.department.getDisplayValue();	
			var manager = gr.manager;

			result.setAttribute("message", "returning information for "+ gr.name);
			//sebd info
			this._addInfo("phone", phone);
			this._addInfo("title", title);
			this._addInfo("site", site);
			this._addInfo("department", department);
			this._addInfo("manager", manager);
			this._addInfo("hire", hire);
		}},

	// all items are returned to the client through the inherited methods of AbstractAjaxProcessor
	_addInfo: function(name, value) { 
		var info = this.newItem("information");
		info.setAttribute("name",name);
		info.setAttribute("value",value); 
	},

	getManagerUserInfo: function(){  

		var user = this.getParameter('sysparm_mgr'); //Get User from Client Script
		var mgrresult = this.newItem('mgrresult');

		var mgr = new GlideRecord('sys_user'); //query user table
		mgr.addQuery('sys_id', user);
		mgr.query();

		if (mgr.next()){
			var phone = mgr.phone;
			var title = mgr.title;
			var site = mgr.location.getDisplayValue();
			var department = mgr.department.getDisplayValue();	
			var manager = mgr.manager;

			mgrresult.setAttribute("message", "returning information for "+ mgr.name);

			this._addMgrInfo("phone", phone);
			this._addMgrInfo("title", title);
			this._addMgrInfo("site", site);
			this._addMgrInfo("department", department);
			this._addMgrInfo("manager", manager);
		}},

	// all items are returned to the client through the inherited methods of AbstractAjaxProcessor
	_addMgrInfo: function(name, value) { 
		var mgrinfo = this.newItem("mgrinformation");
		mgrinfo.setAttribute("name",name);
		mgrinfo.setAttribute("value",value); 
	},

	getUserGroups: function(){  
		//return as criteria string of all groups a member is part of (each one separated by a comma)
		//***COULD NOT GET WORKING RIGHT IN TEST DATA PROJECT, BUT WAS ABLE TO USE ONE OF MY GROUPS INSTEAD
		var groups='';

		//get current user
		var usr = gs.getUserID();

		//query the group member table to get all groups user is part of
		var grps = new GlideRecord('sys_user_grmember');
		grps.addQuery('user', usr);
		grps.query();
     
		//write all groups to string
		while(grps.next()) {
			groups += (',' + grps.group);
		}

		//return criteria string of all groups separated by commas
		//gs.addErrorMessage('sys_idIN' + groups);
		//return 'u_groupIN' + groups;
		return 'u_groupIN' + groups;
	},

	type:"getUserInformation"

});

Here is the Catalog Client Script against the Catalog Item (which is actually in an Order Guide) that actually clears the requested_for field (overrides the default value):

find_real_file.png

 

And here's the Catalog Client Script that acts when they try to select themselves:

find_real_file.png

function onChange(control, oldValue, newValue, isLoading) {
 	if (isLoading || newValue == '') {
 		return;
 	}

	//Get current user
	var user=g_form.getValue('submitter');

	//Get requested for
	var req=g_form.getValue('requested_for');

	//See if user is trying to request for themself
	if (user == req){
		alert("You cannot select yourself as the new hire." +'\n' + "You must wait for the new hire to appear in ServiceNow before submitting request.");
		//clear requested_for field
		g_form.setValue('requested_for','');
		
//***THE FOLLOWING ARE VARIOUS THINGS THAT I TRIED THAT HAVE NO EFFECT***
		//clear all other user/manager fields
		g_form.setReadOnly('department', false);
		g_form.setValue('department','');
		g_form.setReadOnly('department', true);
		
		g_form.setValue('job_title','');
		g_form.setValue('phone','');
		g_form.setValue('site','');
		g_form.setValue('manager','');
		g_form.setValue('manager_department','');
		g_form.setValue('manager_title','');
		g_form.setValue('manager_phone','');
		g_form.setValue('manager_site','');
	}
}

So, as I said, the initial load is fine, it shows a blank form.  The issue occurs when I try to select myself.  It successfully tells me that I cannot do that, and clears the "requested_for" field, but it still populates all the other related fields.  Here is an excerpt of what it looks like after I do that (I am only showing one related field below, but they all behave the same). 

find_real_file.png

I've just setup a quick Catalog Item to simulate your situation.

A catalog Item with only your Catalog Client Script "Ensure submitter etc"

+

Variable Set with variables Submitter (default value: gs.getUserID()), Requested for, Phone + Catalog Client Script which fills the User information together with the script include.

Works fine.

So tested when I will in the same Requested for as the onload Submitter... the alert message indeed + alle fields are made empty 😞

So I only tried to reproduce your situation and made a small Catalog Item with exactly what you provided. No changes, and everything works already. I did not even activate the additional Catalog Client Script which should onLoad clear the requested for.

Or did I miss something? Is your situation still at some point different?

I assume the Submitter is automatically set (default value?). How about the requested for? Is that hand picked or also already set with default value?

If my answer helped you in any way, please then mark it as helpful.

Kind regards,
Mark

---

LinkedIn

 

Kind regards,

 

Mark Roethof

Independent ServiceNow Consultant

10x ServiceNow MVP

---

 

~444 Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

LinkedIn

I don't know if it makes any difference, but these other variables and scripts I am talking about (the ones NOT in the Variable Set) are actually at the Order Guide level, and not directly in a Catalog Item (I made a slight reference to this in my last post).

To answer your questions:

"requested_for" variable is in Variable Set, with default value of "javascript: gs.getUserID();"

"submitter" is in Order Guide, with default value of "javascript: gs.getUserID();"

ahammoud
Tera Guru

Yes the onLoad Catalog Client Script for that specific Catalog Item would be the best approach, but make sure it loads only on The catalog item (No Req Items or Tasks).