Making Better Catalog Macros Part 2

I posted very briefly about this around 2 years ago with the promise that I’d write a second more detailed post. This never happened, but its still one of the things I use all the time. And now Geneva has come along, there’s actually a slight ‘hack’ that’s needed to get it working really properly.

So just to recap, when creating a custom UI macro, to make it work a lot nicer, you should always add this input field to it:

<input id=”$[jvar_question_name]” style=”width:50%” name=”$[jvar_question_name]” value=”” class=”cat_item_option questionsettext”/>

What this would do is let g_form.setDisplay and g_form.setMandatory work with the UI macro. It would also save the value to the database as per any other variable.

Simple enough, but what does this actually do?

Well $[jvar_question_name] is the out of the box jelly variable which stores the question name of the variable. So from the catalog form, it returns IO:sys_id, and on a variable editor will return ni:QSsys_id. The point is, you don’t need to worry about it.

This is the reference that ServiceNow uses for many of it’s g_form functions. When you use g_form.setDisplay(‘fieldname’, true), what it actually does is searches for the real underlying question name. These are all stored in an object called g_form.nameMap where the prettyName attribute stores the field name, and the realName stores what’s in jvar_question_name. Once it finds the underlying name, it can then perform the DOM manipulation that’s required.

So by adding this field, the g_form functions that convert the field name to the real underlying real value are able to locate the elements to perform its function.

What also happens (and this bit I don’t know how it works, I just accept it does), is anything within this field, will be stored in the database like any other variable. So for record producers will be stored within the question_answer table.

Now, this was all pre-Geneva. This ALL still works in Geneva, but ServiceNow edited the UI Macro variable so when it’s created it automatically names a DIV with the real name. This was done so that the g_form functionality would work as it could find the UI elements but what it means is that by adding the above code to the UI macro, you end up with two DOM elements with the same name and ID, which isn’t right.

So the quick hack if you want to use this code, is to remove the values from the DIV so its only stored against the input field:

$$('div[id=${jvar_question_name}]').each(function(e) { = ''; = '';

It is a bit hacky, but it’s required to get it working correctly in Geneva.

So, how can you really use this to your advantage? Well, I’ve created many UI macros which have multiple fields and input types. Ones which include complex data. All of this data can be stored in this single field as a JSON string. What this allows you to do, is when the variable is loaded as part of a variable editor, you’re able to read the JSON string, convert it to an object and then re-populate the UI macro with the original details. This way it’s still useable on both the catalog item and the variable editor


  1. Pingback: Saving UI Macro and Widget Data Automatically | ServiceNow Gems

  2. Pingback: Saving Catalog Widget Data Automatically | ServiceNow Gems

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.