Advanced ServiceNow Catalog Item Development
Advanced Variable Configuration
Crafting Dynamic Forms
You already know how to create basic catalog item variables. Now, let's make them intelligent. Static forms with simple text fields and checkboxes are fine for basic requests, but complex scenarios demand forms that adapt to user input in real-time. This is where advanced variables come into play.
The 'Reference' variable is your gateway to connecting your catalog item to any other table in ServiceNow. But what if you need to filter the choices presented in that reference field based on a previous answer? For instance, showing only the computers assigned to a specific user. For this, you use an Advanced Reference Qualifier.
An Advanced Reference Qualifier uses a JavaScript function to dynamically generate a filter string, giving you precise control over the records a user can select.
Imagine a form where a user first selects their company. A subsequent field should then show only the configuration items (CIs) belonging to that company. You would set the 'Reference qual' field on the CI variable to 'Advanced' and use a script include to define the filtering logic.
javascript:
// In the 'Reference qual' field of the variable:
javascript:new CIUtils().filterCIsByCompany(current.variables.company)
// In a Script Include named 'CIUtils':
var CIUtils = Class.create();
CIUtils.prototype = {
initialize: function() {},
filterCIsByCompany: function(companySysId) {
// If no company is selected, don't show any CIs.
if (!companySysId) {
return 'sys_id=NULL';
}
// Return an encoded query string to filter the CI list.
return 'company=' + companySysId;
},
type: 'CIUtils'
};
This setup calls a script that builds a query string on the fly. It takes the of the selected company and uses it to filter the cmdb_ci table. If the user changes the company, the list of available CIs automatically updates.
To further improve the user experience for reference fields, you can use specific attributes. Setting ref_auto_completer=AJAXTableCompleter enables a powerful search-as-you-type feature. You can then add ref_ac_columns=column1,column2 to display additional columns in the dropdown results, giving users more context to make the right selection.
Managing Multiple Selections
Sometimes a user needs to select more than one item. For requesting access to multiple software applications or selecting several assets for a transfer, a standard reference field won't work. This is the job of the 'List Collector' variable.
The List Collector presents two slush buckets: an 'Available' list and a 'Selected' list. Users can move multiple items from left to right. When the form is submitted, the variable doesn't store a single value. Instead, it stores a comma-separated string of the sys_ids for all selected records.
In your fulfillment scripts or workflows, you'll need to parse this string. You can split the string by the comma to get an array of individual sys_ids, then loop through the array to process each selected record.
// In a script, access the List Collector variable
var selectedApps = current.variables.software_applications.toString();
// Split the comma-separated string into an array of sys_ids
var appArray = selectedApps.split(',');
// Loop through each sys_id to perform an action
for (var i = 0; i < appArray.length; i++) {
var appSysId = appArray[i];
// Add logic here, e.g., create a task for each application
gs.info('Processing access for application: ' + appSysId);
}
Structuring Complex Data
What about when you need to capture data that fits naturally into a table? For example, ordering multiple laptops, each with its own specified RAM, hard drive, and assigned user. Using individual variables for this would create a messy, unscalable form.
The solution is the (MRVS). An MRVS allows you to embed a table-like grid directly within your catalog item form. You define the columns as variables within the set, and the user can then add as many rows as they need, filling out the details for each.
Behind the scenes, the data from an MRVS is stored as a JSON string. To use this data in a workflow or script, you must parse the JSON. The string represents an array of objects, where each object is a row containing key-value pairs for the columns.
Finally, the visual presentation of your form is crucial. A well-organized form is easier to use and less prone to user error. You can control the layout of your variables in the Service Portal by using the 'Variable Width' attribute on the container that holds them.
By default, variables take up 100% of the container's width. You can place variables into 'Container Start' and 'Container End' blocks to group them. Then, on the 'Container Start' element, set the layout to two or three columns. All variables within that container will then take up an equal share of the space, creating a clean, grid-based layout.
| Container Layout | Variable Width |
|---|---|
| 2 Columns at a time | Each variable takes 50% width |
| 3 Columns at a time | Each variable takes 33% width |
| Both sides | Creates a split with a variable on the left and right |
By combining these advanced variable types and layout techniques, you can build sophisticated, user-friendly catalog items that handle even the most complex service requests.
A catalog item requires a user to first select a 'Company', and then a 'Configuration Item' field should only display CIs belonging to that specific company. How should this be implemented?
When a request is submitted from a catalog item containing a 'List Collector' variable, how is the data for the selected items stored in that variable?