- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-19-2017 07:13 PM
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)?
Solved! Go to Solution.
- Labels:
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-13-2019 09:01 PM
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:
- 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 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-19-2017 08:59 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-20-2017 02:30 PM
Hi Raju,
Thanks for your suggestion but g_form.getControl() only returns a field's HTML element (unless I'm missing something?). We were using gel to extract the "current_item" and "sysparm_guide" parameters from the current page URL.
I am trying to compare the order guide sys_id against the catalog item sys_id to determine if the catalog item is being opened in a order guide. I need something that will give us a similar result to determine if we're displaying the first page of the order guide (show common variables) or subsequent items contained in the order guide (hide common variables).
Hope that makes sense.
Thanks in advance
Brent
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-21-2018 12:50 PM
Hi All,
Just trying to reopen this topic as I have not come up with suitable workaround for removing gel or $ from some of our catalog client scripts?
Looking through docs, ServiceNow still shows the technique I am using as appropriate for Jakarta - https://docs.servicenow.com/bundle/jakarta-it-service-management/page/product/service-catalog-manage....
Does anyone know if there is a native function like, g_service_catalog.isOrderGuide(), for desktop in the Kingston release? Otherwise we'll stick with the current technique which ServiceNow have documented in docs.
Any help would be appreciated.
Thanks
Brent
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-13-2019 09:01 PM
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:
- 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 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.