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

Brad Bowman
Kilo Patron
Kilo Patron

Hi Ben,

Here's one approach:

BradBowman_0-1700478998914.png

You would select the class from a drop-down (lookup select box) then in a multi-row variable set you can add a row for each field and value that you want to populate when creating the CI.  The column names will be filtered to only include those on the table for that class (and extended from cmdb_ci.  If you have a script in the workflow to automatically create the CI, it can loop through the MRVS rows to assign the values to each column.  Let me know if you want the details on how to make this work.

Thanks Brad

I was also thinking of doing it this way. I had a go but wasn't able to get the linkage from CI Class to lookup the fields for that Class in MRVS.

If you could provide the details on your approach, that would be much appreciated.

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);
	}
}

 

 

Hi @Brad Bowman  ,

 

I found a way to grab a catalog item variable from MRVS and use that value for ref qual/filtering purposes within MRVS. It requires a couple of onLoad client scripts: one for catalog item and one for MRVS.

 

onLoad client script on catalog item:

function onLoad() {
    //Type appropriate comment here, and begin script below
    if (this) {
        this.cat_g_form = g_form;
    }
}

 

onLoad client script on MRVS, specifically with the use case of filtering down the returned records of that 'field' variable that references sys_dictionary based on selected CI class variable (thus ref qual on the field variable itself should be left empty):

function onLoad() {
    //Type appropriate comment here, and begin script below
    if (this) {
        var ciClass = this.cat_g_form.getValue('ci_class');
        var filter = g_list.get('field');
        filter.setQuery('active=true^name=' + ciClass + '^internal_type=string');
    }
}

 

If this answer is helpful please mark correct and helpful!

Regards,
Chris Perry