
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-23-2019 01:00 AM
Hi,
In my company we use the Client Software Distribution integration with SCCM. We don't like how it appears on the portal - we got 100+ software items so you get a really long list, where you have to click "show more" xx number of times to see it all.
I'd like build an Order guide for this instead. My idea was to let the user select the software on the first page of the order guide and then fill in the related catalog item for the specified software on the next page.
I've build an order guide with a variable of the type "Lookup Select Box" for table: "sn_client_sf_dist_cat_item" - which is where the software items are located (the sc_cat_item table would also work, with some filtering). This seems to work fine when there are rule bases for it, but the problem is that I would need a rule base for each piece of software on the list, and this number grows all the time. We got another team for handling/creating the software items and they do not have access to modifying the order guide and I'd prefer them not to have, so ideally I was thinking there must be a way around this with a script.
I've discovered that the order guide takes the script code:
guide.add("sys_id of catalog item");
So adding this line will force the order guide to include the specified catalog item.
But here I lack some coding skills.. Can I combine this with the input from my variable?
I've tried with numerous variations of:
guide.add("current.variables.variable");
but it doesn't work. I cannot fetch the variables from the Order Guide - and even if I could, the script field on Order Guides is running server side. So how do I pull the the value of the variable and insert into the guide.add(); ?
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-02-2020 08:03 PM
Hey Jesper,
I've had a read through you problem and before we start digging in to code and hacky solutions, have you taken a step back and considered that swapping a list of 100+ items for a single item with a list of 100+ options in a Lookup Select Box may not be the quick fix you are after?
Are there any other options to increase the usability of your catalog items rather than the solution proposed?
Have you considered:
- Pushing a Search-first approach to your catalog items / software? Make sure the Meta tags are accurate and users shouldn't need to look through a list of software
- Make a Dynamic Category based on the most requested items? Surely there would be 5 - 10 or so software items that get requested more than anything else, so using the 80/20 rule you could capture most cases with a quick sort, and for the edge cases push to search
- Create a useful and meaningful category tree? If you look at the items and think about how they could be categorised (e.g. Development Tools, Productivity Tools, etc) you may be able to come up with almost a decision tree in categories that each item could be placed in to make them easier to find.
There are always many ways to solve problems, and often the "let's fix it with code" response isn't going to get you the best outcome, and it adds maintenance issues of it's own.
I hope this helps,
Andrew

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-08-2021 05:43 AM
Hi Torsten,
Looks good! And thanks for bringing this up, it's still relevant for me, as we never got a good solution for this.. not much luck with dynamic categories or searching.
When I know the sys_id of the catalog item up front, then I can make it work. But what I was struggling with back then, was pulling the sys_id from a variable and then inserting it into the script.
I wanted to make variable as a drop down reference (or maybe some kind of multiple select) to the catalog item table, with all available active software catalog items. Then when the end-user chose some software from the list, this would be added to the order guide, so I wouldn't have to build a rule base each and every time we added some software to the catalog.
I'm still no superhero when it comes to scripting - back then I came into conflict with serverside and client side script, when trying to read the sys_id from the order guide variable dropdown/list. Do you reckon that ajax could help here?
Kr
Jesper

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-08-2021 06:31 AM
Hi,
Yes, what was described above would be what you'd want to implement. So an onChange client script on that variable that contains a reference to your catalog items and inside that onChange client script, you'd take that selection and pass it via GlideAjax to your script include, where you query the cart and add the catalog item to it using:
guide.add('sys_id_of_catalog_item');
Opposite can be done if you need to remove it by doing:
guide.remove('sys_id_of_catalog_item');
Here's a link to a GlideAjax cheat sheet to get you started: https://community.servicenow.com/community?id=community_article&sys_id=9f7ce2e1dbd0dbc01dcaf3231f961...
And then the onChange client script
Please mark reply as Helpful, if applicable. Thanks!
Please consider marking my reply as Helpful and/or Accept Solution, if applicable. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-08-2021 04:18 PM
Hi Jesper, sure it can.
On each variable add a client script on change to update the cart record.
If Variable is a drop down you can store the ID of the cat Item on the cart, you can go nuts here 🙂 Blank canvas
function onChange(control, oldValue, newValue, isLoading) {
if (newValue == '') {
g_form.setValue("applications", [], []);
g_form.setValue("ad", [], []);
return;
}
var ga = new GlideAjax('OrderGuideAjax');
ga.addParam('sysparm_name', 'checkAccount');
ga.addParam('sysparm_var_value', newValue);
ga.addParam('sysparm_var_user', g_user.userID);
ga.getXML(callBackFunc);
}
function callBackFunc(response) {
// Nothing really to do here but here you can change Variables based on the Ajax Script (Server Side) Outcome
}
Ajax Script Include to store variables - in my case special_instructions (for my POC). You can add a new field if you wish.
var OrderGuideAjax = Class.create();
OrderGuideAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
initialze: function() {
gs.debug("OrderGuideAjax CALL INIT");
},
addVariable: function() {
this.initialze();
gs.info("OrderGuideAjax");
gs.info("myAjaxGlobal STATE: " + this.STATE.NEW);
var name = this.getParameter('sysparm_var_name');
var user = this.getParameter('sysparm_var_user');
var value = this.getParameter('sysparm_var_value');
var cartRec = new GlideRecord('sc_cart');
cartRec.addQuery("user", user);
cartRec.query();
if (cartRec.next()) {
try {
var json = JSON.parse(cartRec.special_instructions);
json[name] = value;
} catch (e) {
var json = {};
json[name] = value;
}
cartRec.special_instructions = JSON.stringify(json);
cartRec.update();
return (JSON.stringify({
ret: true,
json: json
}));
}
return (JSON.stringify({
ret: false
}));
},
type: 'myAjaxGlobal'
});
You should work out the rest!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-13-2021 05:23 AM
Wow! Thanks. I'll try it out!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-18-2022 02:17 AM
Hello,
Thanks for sharing this.
I think this should solve my issue but I'm having hard time to make it works.
I want to create an order guide with possibility to select among all catalog items (100+ items). Thus, I can't create base rules for each items neither use catalog items variables sysID in order guide script. So I think this is kind of the same situation as Jesper.
I'am trying your solution, I replaced the value "application" in the Catalog Client Script by "og_dm_catalog_item_1", which is the name of my variable Reference to Catalog Item [sc_cat_item] (the item that will be selected by user basically):
function onChange(control, oldValue, newValue, isLoading) {
if (newValue == '') {
g_form.setValue("og_dm_catalog_item_1", [], []);
g_form.setValue("ad", [], []);
return;
}
var ga = new GlideAjax('OrderGuideAjax');
ga.addParam('sysparm_name', 'checkAccount');
ga.addParam('sysparm_var_value', newValue);
ga.addParam('sysparm_var_user', g_user.userID);
ga.getXML(callBackFunc);
}
function callBackFunc(response) {
// Nothing really to do here but here you can change Variables based on the Ajax Script (Server Side) Outcome
}
In the Script Include, I replaced "special_instructions", by "sys_id" to get the variable sysID of the item selected by user. I also tried "value", "variable_name", "catalogFieldName",... but none of these work:
var OrderGuideAjax = Class.create();
OrderGuideAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
initialze: function() {
gs.debug("OrderGuideAjax CALL INIT");
},
addVariable: function() {
this.initialze();
gs.info("OrderGuideAjax");
gs.info("myAjaxGlobal STATE: " + this.STATE.NEW);
var name = this.getParameter('sysparm_var_name');
var user = this.getParameter('sysparm_var_user');
var value = this.getParameter('sysparm_var_value');
var cartRec = new GlideRecord('sc_cart');
cartRec.addQuery("user", user);
cartRec.query();
if (cartRec.next()) {
try {
var json = JSON.parse(cartRec.sys_id);
json[name] = value;
} catch (e) {
json = {};
json[name] = value;
}
cartRec.sys_id= JSON.stringify(json);
cartRec.update();
return (JSON.stringify({
ret: true,
json: json
}));
}
return (JSON.stringify({
ret: false
}));
},
type: 'myAjaxGlobal'
});
This is my very first script in ServiceNow so I'm struggling to understand what I'm missing here...
If anyone could help I would be very thankfull !