Hiding Order Guide cascading variables on Desktop - DOM issues

Brent Sutton
Mega Sage

In preparation for our upgrade to Kingston we have run an ACE report to pick up any potential issues. The report is highlighting a number of catalog client scripts that are using a DOM technique (gel) to determine whether to hide cascading variables when initiated from an Order Guide (sample code below):

var item = gel("current_item");

var guide = gel("sysparm_guide");

if (item != null && guide != null && item.value != guide.value) {

        g_form.setDisplay('variable_to_hide_1',false);

        g_form.setDisplay('variable_to_hide_2',false);

}

This code is only required to hide variables when catalog item is opened in the desktop (our Service Portal code is fine) and is actually derived from ServiceNow's own docs website: - https://docs.servicenow.com/bundle/helsinki-it-service-management/page/product/service-catalog-manag...

Has anyone come up with an alternative technique to hide cascading variables, on the desktop, that doesn't use the DOM ($, gel)?

1 ACCEPTED SOLUTION

Brent Sutton
Mega Sage

I recently came up with a solution to the issue of cascading variable scripts failing when migrating to London from an older ServiceNow instance.

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 direct access to the DOM.

This technique tests for the availability of g_service_catalog.isOrderGuide() API which is only available in Service Portal/Mobile and then reverts to the desktop code. I utilised g_form.getControl(String fieldName) 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
	*/
	
	/*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();
		}
	}
	/*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 the 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(); //hide the variables if the above conditions weren't met.
		}
	}

	function hideVariables(){
		//variables to be hidden need to be not mandatory before setting display to false.
		g_form.setMandatory("<your_variable_here>",false);
		g_form.setDisplay("<your_variable_here>",false);
	}
}

Hope this information helps.

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

6 REPLIES 6

Your non-DOM example worked perfectly for me, thanks!

Glad it worked for you, Kevin. Think this information is pretty valuable to everyone so have transferred it into the following article:

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

Brent

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