Solved: Hide Variable Set on Back end order Guide - ServiceNow Community

Hide Variable Set on Back end order Guide

snuser10
Kilo Expert

Hello - I'm trying to hide Order Guide variable set from catalog items when a user tries to submit an Order Guide. 

To do this, I've below catalog client script which works great when a user submit the order guide from the service portal but the same variable set is not hidden on the backend (https://instancename.service-now.com > Service Catalog > Order Guide). 

 

Any items on how to achieve this? Below script doesn't work for backend order guide:

 

function onLoad() {
var isOrderGuide = g_service_catalog.isOrderGuide();
if(isOrderGuide){
g_form.setDisplay('firstvariable', false);
g_form.setDisplay('secondvariable', false);

}
}

1 ACCEPTED SOLUTION

Brent Sutton
Mega Sage

Hi Ya,

I know this is a slightly older thread but I have recently come up with a solution to the issue of cascading variable scripts failing when migrating to London from older ServiceNow instances.

Hide Cascading Variables

As of London, client scripts now have "Isolate script" set to true as default. This means the client script runs in "strict mode" which prevents direct access to the DOM. Unfortunately, the ServiceNow prescribed method to hide cascaded variables uses DOM techniques so the old scripts fail when upgrading to London.

Luckily there is an easy method to disable "Isolate script" on a script by script basis:

Instructions:

  1. Right Click Header >> Configure >> Form Layoutfind_real_file.png
  2. Add "Isolate script" to form >> Save.find_real_file.png
  3. Deselect the "Isolate script" checkbox.find_real_file.png
  4. Save Client Script.

Your old code should now run as expected

Example Code:

function onLoad() {
	
	//window object will not be available to Service Portal or mobile
	if (window === null) {
		// check if we are in an order guide using the g_service_catalog api for Service Portal and Mobile
		var isOrderGuide = g_service_catalog.isOrderGuide();
		
		if (isOrderGuide) {
			//call function to hide the fields on the catalog items if this is an order guide.
			hideVariables();
		}
	}
	else {
		var item = gel("current_item");
		var guide = gel("sysparm_guide");

		if (item != null && guide != null && item.value != guide.value) {
			hideVariables();
		}
	}
	
	function hideVariables(){
		g_form.setMandatory('<your_variable_here>',false);
		g_form.setDisplay('<your_variable_here>',false);
	}
}

However, when looking for solutions to this problem I came up with a slightly different approach that does not use the DOM. This technique tests for the availability of "g_service_catalog.isOrderGuide()" which is only available in Service Portal/Mobile and then reverts to the desktop code. I utilised an API called g_form.getControl to extract the guide and item sys_id's for the compare required for the desktop code:

Example no direct access to DOM code:

function onLoad() {
	/*in strict mode ("Isolate script" is true) we don't have access to the window object so it will return null for Service Portal/Mobile and desktop
	* instead we use a try/catch block to test if we have access to g_service_catalog which is only available in Service Portal/Mobile
	*/
	
	//create array with internal variable names to hide
	var varsToHide = ["your_variable_1","your_variable_2","your_variable_3"];
	
	/*Service Portal/Mobile code
	____________________________________________________________________________________________________*/
	try {
		//check if we are in an order guide using the g_service_catalog api for Service Portal and Mobile
		var isOrderGuide = g_service_catalog.isOrderGuide();

		if (isOrderGuide) {
			//call function to hide the fields on the catalog items if this is an order guide.
			hideVariables(varsToHide);
		}
	}
	/*Desktop code
	____________________________________________________________________________________________________*/
	catch(e) {
		/* test that error message relates to g_service_catalog then execute desktop only code. 
		*/
		if (/g_service_catalog is not defined/.test(e.message)) {
			var item = g_form.getControl("current_item"); //sys_id of the current item
			var guide = g_form.getControl("sysparm_guide"); //sys_id of the order guide

			//check if both HTML elements were returned.
			if (item == null && guide == null) {
				return; //return as we are not in a order guide
			}

			//test that both HTML elements were returned and whether they are equal to each other.
			if (item != null && guide != null && item.value == guide.value) {
				return; //return as we are on the "Describe Needs" section of the order guide
			}
			hideVariables(varsToHide); //hide the variables if the above conditions weren't met.
		}
	}

	function hideVariables(varsArray){

		for (var i=0; i< varsArray.length; i++) {
			//variables to be hidden need to be not mandatory before setting display to false.
			g_form.setMandatory(varsArray[i],false);
			g_form.setDisplay(varsArray[i],false);
		}
	}
}

Let me know if this works for your use case.

Brent

P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.

View solution in original post

5 REPLIES 5

Brent Sutton
Mega Sage

Hi Ya,

"g_service_catalog" is only available from the Service Portal so will fail on the platform side. Please take a look at my article for hiding cascading variables. This has the code for hiding variables on Service Portal and the platform in one client script - 

Order Guide - Hide Cascading Variables, for Service Portal and Desktop, in single client script - No...

Let me know how you get along.

Brent

P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information. 

Thank you for your quick response. Not sure why my onLoad catalog client script on order guide isn't working. I have below on London:

 

function onLoad() {
if (window === null) {
// check if we are in an order guide using the g_service_catalog api for Service Portal and Mobile
var isOrderGuide = g_service_catalog.isOrderGuide();

if (isOrderGuide) {
//call function to hide the fields on the catalog items if this is an order guide.
hideVariables();
}
}
else {
var item = g_form.getControl('current_item');
var guide = g_form.getControl('sysparm_guide');
if (item != null && guide != null && item.value != guide.value) {
hideVariables();
}
}
function hideVariables(){
g_form.setDisplay('added_variable_name_1', false);
g_form.setDisplay('added_variable_name_2', false);
}
}

Brent Sutton
Mega Sage

Hi Ya,

I know this is a slightly older thread but I have recently come up with a solution to the issue of cascading variable scripts failing when migrating to London from older ServiceNow instances.

Hide Cascading Variables

As of London, client scripts now have "Isolate script" set to true as default. This means the client script runs in "strict mode" which prevents direct access to the DOM. Unfortunately, the ServiceNow prescribed method to hide cascaded variables uses DOM techniques so the old scripts fail when upgrading to London.

Luckily there is an easy method to disable "Isolate script" on a script by script basis:

Instructions:

  1. Right Click Header >> Configure >> Form Layoutfind_real_file.png
  2. Add "Isolate script" to form >> Save.find_real_file.png
  3. Deselect the "Isolate script" checkbox.find_real_file.png
  4. Save Client Script.

Your old code should now run as expected

Example Code:

function onLoad() {
	
	//window object will not be available to Service Portal or mobile
	if (window === null) {
		// check if we are in an order guide using the g_service_catalog api for Service Portal and Mobile
		var isOrderGuide = g_service_catalog.isOrderGuide();
		
		if (isOrderGuide) {
			//call function to hide the fields on the catalog items if this is an order guide.
			hideVariables();
		}
	}
	else {
		var item = gel("current_item");
		var guide = gel("sysparm_guide");

		if (item != null && guide != null && item.value != guide.value) {
			hideVariables();
		}
	}
	
	function hideVariables(){
		g_form.setMandatory('<your_variable_here>',false);
		g_form.setDisplay('<your_variable_here>',false);
	}
}

However, when looking for solutions to this problem I came up with a slightly different approach that does not use the DOM. This technique tests for the availability of "g_service_catalog.isOrderGuide()" which is only available in Service Portal/Mobile and then reverts to the desktop code. I utilised an API called g_form.getControl to extract the guide and item sys_id's for the compare required for the desktop code:

Example no direct access to DOM code:

function onLoad() {
	/*in strict mode ("Isolate script" is true) we don't have access to the window object so it will return null for Service Portal/Mobile and desktop
	* instead we use a try/catch block to test if we have access to g_service_catalog which is only available in Service Portal/Mobile
	*/
	
	//create array with internal variable names to hide
	var varsToHide = ["your_variable_1","your_variable_2","your_variable_3"];
	
	/*Service Portal/Mobile code
	____________________________________________________________________________________________________*/
	try {
		//check if we are in an order guide using the g_service_catalog api for Service Portal and Mobile
		var isOrderGuide = g_service_catalog.isOrderGuide();

		if (isOrderGuide) {
			//call function to hide the fields on the catalog items if this is an order guide.
			hideVariables(varsToHide);
		}
	}
	/*Desktop code
	____________________________________________________________________________________________________*/
	catch(e) {
		/* test that error message relates to g_service_catalog then execute desktop only code. 
		*/
		if (/g_service_catalog is not defined/.test(e.message)) {
			var item = g_form.getControl("current_item"); //sys_id of the current item
			var guide = g_form.getControl("sysparm_guide"); //sys_id of the order guide

			//check if both HTML elements were returned.
			if (item == null && guide == null) {
				return; //return as we are not in a order guide
			}

			//test that both HTML elements were returned and whether they are equal to each other.
			if (item != null && guide != null && item.value == guide.value) {
				return; //return as we are on the "Describe Needs" section of the order guide
			}
			hideVariables(varsToHide); //hide the variables if the above conditions weren't met.
		}
	}

	function hideVariables(varsArray){

		for (var i=0; i< varsArray.length; i++) {
			//variables to be hidden need to be not mandatory before setting display to false.
			g_form.setMandatory(varsArray[i],false);
			g_form.setDisplay(varsArray[i],false);
		}
	}
}

Let me know if this works for your use case.

Brent

P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.

A quick note to anyone following this thread.

I moved this solution to an article which I keep updated as I make any code improvements. Please take a look at Order Guide - Hide Cascading Variables, for Service Portal and Desktop, in single client script - No....

Please feel free to bookmark or subscribe to the article so you receive notification to any updates.

Brent