- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2019 02:20 PM
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);
}
}
Solved! Go to Solution.
- Labels:
-
Request Management
-
Service Catalog
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-14-2019 04:52 PM - edited 09-26-2023 03:03 PM
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:
- Right Click Header >> Configure >> Form Layout
- Add "Isolate script" to form >> Save.
- Deselect the "Isolate script" checkbox.
- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2019 03:41 PM - edited 09-26-2023 03:37 PM
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 -
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 05:42 AM
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);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-14-2019 04:52 PM - edited 09-26-2023 03:03 PM
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:
- Right Click Header >> Configure >> Form Layout
- Add "Isolate script" to form >> Save.
- Deselect the "Isolate script" checkbox.
- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 04:12 PM
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