Catalog Item - Add fields dynamically based on a class. Mimic the ATF:Set field values step

B3N_AU
Tera Guru

Hi,

I have a requirement to create a catalog item for the creation of new CIs. You should be able to have a drop down of all of the available fields based on a class.

I don't want to re-invent the wheel. Is there anything OOB that might do this?

What I had in mind was something like the ATF:Set field values step. This allows you to select the class/table and then add one or many field values.

B3N_AU_0-1700428504829.png

Is there a way to achieve this in a catalog item?

 

Cheers Ben

1 ACCEPTED SOLUTION

I think I know what's thwarting you, but I'll start at the beginning just so it's clear for others.

 

The CI Class variable that belongs to the Catalog Item I'll name ci_class, and it's the Type of Lookup Select Box

BradBowman_0-1700525342274.png

In the MRVS we need (at least) 3 variables

BradBowman_1-1700525446107.png

The Field variable has an important Reference qualifier and Variable attribute

BradBowman_2-1700525531484.png

Unfortunately, there's not (yet?) a way for a reference qualifier to use variables not in the MRVS, so that's why we need the Class variable repeated in the MRVS.  The attribute ensures that the Field lookup select box will update to only show columns in the table that matches the Class that you selected outside of the MRVS when this value changes (from blank and/or one choice to another).

 

There's nothing notable about the Value variable.  You can make the Class variable hidden and/or Read only if you'd like.  Note that 'hidden', as shown in my example data, only hides it on the Add Row / Edit Row dialog window, it cannot be hidden in the display of the full MRVS contents.

 

The last piece is an onLoad Catalog Client Script that applies to the MRVS to populate the Class variable in the MRVS from the Class variable in the Catalog Item.  Here's that magic:

function onLoad() {
	g_form.setValue('class_mrvs', g_service_catalog.parent.getValue('ci_class'));
}

A variation I just thought of, if you prefer, would be to get rid of the Class variable in the Catalog Item, move the one in the MRVS to 100 and make it the same Lookup Select Box as shown earlier.  You would then pick a Class for the first row, and we would change the onLoad script to 1) make this variable read only if it has a value, so a troublesome user can edit a row, change the class, then wonder why the field is wrong, and 2) auto-populate subsequent rows with the class selected in the first row and make it read only so you don't have to pick a class for every row, and there's no possibility of mixing classes within the MRVS.  Here's what that would look like instead of the one line onLoad Catalog Client Script in the MRVS:

function onLoad() {
    if (g_form.getValue('class_mrvs') != '') {
        g_form.setReadOnly('class_mrvs', true);
    }
	var mrvs = g_service_catalog.parent.getValue('create_ci'); //internal name of your MRVS
	if (mrvs.length > 2) { //native UI returns [] for empty MRVS value, which causes a parsing error
		var obj = JSON.parse(mrvs);
		g_form.setValue('class_mrvs', obj[0].class_mrvs);
		g_form.setReadOnly('class_mrvs', true);
	}
}

 

 

View solution in original post

9 REPLIES 9

@chrisperry hey that's handy - nice work!!!  With the advent of g_service_catalog, the Catalog Item onLoad script is no longer needed (unless setting a value of a Catalog Item variable from a MRVS script in Service Portal) and since the script (g_list) only works in Service Portal, but even if the script UI Type is set to 'All' it doesn't present an error in the native UI, the MRVS script could be shortened to: 

 

 

function onLoad() {
    var ciClass = g_service_catalog.parent.getValue('cat_item_var_name');
    var filter = g_list.get('mrvs_var_name');
    filter.setQuery('active=true^name=' + ciClass + '^internal_type=string');
}

 

 

What is that last bit needed for: internal_type=string ?  Do you have any other tricks up your sleeve for an alternative that works in the native UI, even if it uses DOM?

 

@chrisperry do you participate in Hacktoberfest?  I was thinking of submitting like this to the Code Snippets repo as a collaboration, unless you'd rather submit your approach yourself.

Hey Brad,

 

Sorry for the delayed reply! That is good to know about g_service_catalog, I wasn't aware of that one.

 

As far as the last bit of my setQuery for internal_type=string, that was more in the context of this specific MRVS and its ability to select and set field values on a new CI record. Because the answer/input variable in the MRVS is variable type = single line text, I figured it made sense to only allow end-users to select fields with type = String.

 

I do not participate in Hacktoberfest, or at least have not thus far 🙂 Please feel free to submit as a collaboration, thank you!

If this answer is helpful please mark correct and helpful!

Regards,
Chris Perry

Brad Bowman
Kilo Patron
Kilo Patron

I came up with a way to do this that works on both Service Portal,... and the native UI, though it's not as streamlined as the Portal g_list/setQuery approach

https://www.servicenow.com/community/now-platform-articles/yes-you-can-effectively-set-or-update-a-r... 

Awesome stuff, thanks @Brad Bowman  !

If this answer is helpful please mark correct and helpful!

Regards,
Chris Perry