logo

NJP

How to access Order Guide variables for use in Order Guide script

Import · Jun 24, 2022 · article

Have you ever had a need to be able to access Order Guide variables within the Order Guide script field?

Within Order Guides there really isn't an efficient way to access the Order Guide variables within the Order Guide script field as easy as you can within a Record Producer. Within a Record Producer, you can access the variables by simply using: producer.variable_name.

For Order Guides, sure you can cascade the values and/or use a "Rule base" to look at the variables and their values and then add catalog items dynamically that way or set specific field values on that catalog item based on an order guide variable's value, but we're talking about the Order Guide script field.

image

The Order Guide script field is executed once you click the "Next" or "Choose Options" button on the initial order guide page and proceed to the next steps.

Possible Use Cases: Common use cases for this script field is to dynamically add catalog items to the order guide process in an automated way when you're in a situation where you may not want to setup your Rule base to house tons of catalog items (i.e., you need to check a value on another table, then based on that and various Order Guide variable values, you may need to add 5 random catalog items for this user). Another use case could be that you need to execute some sort of server side script to capture something somewhere else and need access to the Order Guide variables and their values to complete this task.

In any case, previously, this question has mostly gone unanswered or partially answered. For example, there's been the suggestion to use something like this in the order guide script field to get the value of a particular Order Guide variable:

g_request.getParameter('IO:sys_id_of_variable')

But that doesn't work on the Portal...

Then there's actually a way to access the Order Guide variables and their values within the sc_cart record for the user as the data is captured within the "Current guide serial" field, but it contains the variable sys_ids without their variable names and requires you to either use that variable sys_id or do a lookup within the database and retrieve the variable name (or label) and even then it's still a bit of a mess that you have to filter through as it's just one massive block of string, example:

image

Who knows, maybe you didn't even know about that field and want to stop reading here and can use that and you'll take it from here. If so, by all means, go for it!

Use Case for this Article: Let's say we have a New Hire order guide and based on the value of the order guide reference variable "hiring_group", this determines if we need to add a specific catalog item to this process. That catalog item is saved in a separate reference field within the selected group's sys_user_group record.

Solution: The solution I'm proposing helps organize things a bit more and makes it easier to use the data to then do whatever you need to do. It requires an onChange Client Script for each of the variables where you'd like to capture both the variable name and the value and uses GlideAjax to communicate with a script include. A client callable script include to be leveraged by the GlideAjax call which executes server script to record the data to the user's relevant service catalog cart record. And then of course the script you need in your Order Guide script field.

Solutions Steps:

  1. Create a client callable script include named: orderGuideVars and check the "Client callable" checkbox prior to writing any script:
    imageAnd the full script can look like this (you can copy and paste the entire thing and replace what you have):
    var orderGuideVars = Class.create(); orderGuideVars.prototype = Object.extendsObject(AbstractAjaxProcessor, { addVariable: function() { var guideID = this.getParameter('sysparm_guideID'); //retrieves the order guide sys_id from the client script var varName = this.getParameter('sysparm_varName'); //retrieves the order guide variable field name from the client script var varValue = this.getParameter('sysparm_varValue'); //retrieves the order guide variable value from the client script var userID = this.getParameter('sysparm_userID'); //retrieves the current user's sys_id from the client script var obj; //declares a JavaScript variable called obj for use later in the script //declares a JavaScript variable called runUpdate that will run function updateCart passing in parameters that we retrieve earlier in this script //the function will return true if a cart record associated with the order guide is found for this user //the function will return false if no cart record associated with the order guide is found for this user var runUpdate = updateCart(guideID, varName, varValue, userID); if (!runUpdate) { //if runUpdate equals false //execute function updateDefault to instead update the default cart record for this user passing in just the variable name, variable value, and the user's sys_id we retrieved earlier in this script updateDefault(varName, varValue, userID); } function updateDefault(varName, varValue, userID) { var gr = new GlideRecord('sc_cart'); //preparing to query the sc_cart table gr.addQuery('name', "DEFAULT"); //filter for records where the name is DEFAULT gr.addQuery('user', userID); //filter for record's associated to user's sys_id gr.query(); //execute the query if (gr.next()) { //if a record is found that matches the above, proceed try { //try the below first obj = JSON.parse(gr.special_instructions); //set JavaScript variable 'obj' to the parsed value of the special instructions field obj[varName] = varValue; //set the key value pair related to the order guide variable name and value, within the object } catch (e) { //if an error occurs from the above, proceed with catch obj = {}; //set JavaScript variable 'obj' as an object obj[varName] = varValue; //set a key value pair related to the order guide variable name and value, within the object } gr.setValue('special_instructions', JSON.stringify(obj)); //set the special instructions field to the stringified JavaScript variable 'obj' gr.update(); //update the cart record } return true; //return true } function updateCart(guideID, varName, varValue, userID) { var gr = new GlideRecord('sc_cart'); //preparing to query the sc_cart table gr.addQuery('current_guide', guideID); //filter for records that have the current guide field related to the order guide gr.addQuery('user', userID); //filter for record's associated to user's sys_id gr.query(); //execute the query if (gr.next()) { //if a record is found that matches the above, proceed try { //try the below first obj = JSON.parse(gr.special_instructions); //set JavaScript variable 'obj' to the parsed value of the special instructions field obj[varName] = varValue; //set the key value pair related to the order guide variable name and value, within the object } catch (e) { //if an error occurs from the above, proceed with catch obj = {}; //set JavaScript variable 'obj' as an object obj[varName] = varValue; //set a key value pair related to the order guide variable name and value, within the object } gr.setValue('special_instructions', JSON.stringify(obj)); //set the special instructions field to the stringified JavaScript variable 'obj' gr.update(); //update the cart record return true; //return true } else { return false; //return false } } return ''; //return null to client script -- nothing is really needed to go back to the client script anyway }, type: 'orderGuideVars' });
  2. Create an onChange Client Script for however many order guide variables you want to capture the name and value of. It's recommended to use settings like this:
    imageAnd the full script can look like this (you can copy and paste the entire thing and replace what you have):
    function onChange(control, oldValue, newValue, isLoading) { if (isLoading || newValue == '') { return; } var guideID; //creating JavaScript variable called guideID if (g_form.getUniqueValue()) { //if g_form.getUniqueValue() returns a valid value, then proceed guideID = g_form.getUniqueValue(); //sets the JavaScript variable 'guideID' to the sys_id of the order guide - Portal UI } else { //if g_form.getUniqueValue() returns an invalid value, then proceed guideID = g_form.getParameter('sysparm_guide'); //sets the JavaScript variable 'guideID' to the sys_id of the order guide - Platform UI } var ga = new GlideAjax('orderGuideVars'); //preparing a call to the script include 'orderGuideVars' ga.addParam('sysparm_name', 'addVariable'); //calling the specific function in the orderGuideVars script include called addVariable ga.addParam('sysparm_guideID', guideID); //passing the order guide sys_id to the script include ga.addParam('sysparm_varName', 'replace_with_order_guide_variable_name'); //passing the order guide variable name to the script include ga.addParam('sysparm_varValue', newValue); //passing the new value selected for this order guide variable to the script include ga.addParam('sysparm_userID', g_user.userID); //passing the current user's sys_id to the script include ga.getXMLAnswer(callBackFunc); //executing the GlideAjax call } function callBackFunc(response) { //receiving response from the script include -- no real response is needed // }
  3. Lastly, you can now parse the special instructions field on the current record to then add a catalog item as you need. You can access any order guide variable that you used the onChange Client Script with by referring to it as: obj.variable_name. In this case, we will query the sys_user_group table and use the hiring_group order guide variable (that we're using in this example use case) to retrieve the custom field's value we placed on the group table that houses the special catalog item we want to add to this order guide process. The script would look something like this:
    var getCart = new GlideRecord('sc_cart'); //preparing to query the sc_cart table getCart.get(current.sys_id); //retrieving the current order guide record for this user var obj = JSON.parse(getCart.special_instructions); //setting the JavaScript variable 'obj' to the parsed value of the special instructions field on the retrieved sc_cart record found above var getItem = new GlideRecord('sys_user_group'); //preparing to query the sys_user_group table getItem.get(obj.hiring_group.toString()); //retrieving the hiring group's group record that was selected on the order guide form guide.add(getItem.getValue('u_custom_catalog_item')); //adding the special catalog item to this order guide process that is listed on the hiring group's group record
  4. Additional note, you can also use guide.remove('sys_id_of_catalog_item'); as well, if needed

Documentation: Order Guide Script field: https://docs.servicenow.com/en-US/bundle/sandiego-servicenow-platform/page/product/service-catalog-m...

----------

Shoutout/Additional Credit: I want to give a special shoutout to @themasterofthecloud (Torsten Brosow) who initially brought this to my attention about a year ago in another thread located here: https://community.servicenow.com/community?id=community_question&sys_id=d6170bc7dbb5c890414eeeb5ca96...

Since then, I've seen this question pop-up a few times and I hadn't really had the time to take things a bit further and write an article, but...better late than never, so here it is. I've taken what was discussed in that thread and then tweaked things a bit to ensure it works in a wider setting, for the right user, for the right service catalog cart record.

----------

If you have any questions/concerns/issues, feel free to comment below

*Please don't forget to mark this article as Helpful and Bookmark it!

Thank you and take care!

Labels:

image

View original source

https://www.servicenow.com/community/developer-articles/how-to-access-order-guide-variables-for-use-in-order-guide/ta-p/2300620