How can I create a new custom listview for a table using script?

Hoan Pham
Kilo Contributor

I have created a new table, inherit from cmdb_ci, with additional columns and populated with data.

I want to create a new list view via script, not GUI. Has anyone did this before? Can someone guide me/ show me the script?

GUI equivalent: Click on "Column options" > Configure > List Layout.

In short, I would like to solve in script form:

- Define a new list view, with all columns I want.

- Set the table to use this list view as default. 

Thanks.

4 REPLIES 4

Pranesh072
Mega Sage
Mega Sage

You can glide query the sys_ui_list table and update the list elements in it.

 

find_real_file.png

Harika Bhupathi
Giga Guru

Hi @Hoan Pham 

Create a new view 

You can create a UI policy or on load client script

 

uncheck the global field in UI policy / client script and give the view name in view field

 

find_real_file.png

 

and create UI Policy actions for the fields setting visible to true

 

same way in client script you can uncheck global field and give view name 

 

in script use g_form.setVisibile('field_value',true);

 

Please do mark my answer as correct or helpful if it resolved your issue

Regards,

Harika

Hoan Pham
Kilo Contributor

Hi,

I got help from colleagues to solve the script:

The main steps are:

You need Table to get the view, use View to get the List, use List to get listId (sys_id of the list object), and finally use listId to create/insert list-element(s).

Overview:

- Parameter in: tableName, viewLabel, fields[]

- Table must exist, use GlideRecord('sys_db_object') lookup the table.

- Check if view exists, remember to convert view label to view name. Use 'sys_ui_view' to lokkup. If view not exists then create/insert new view object. Save the view object (either existing one or newly created)

- Check if list exists (for this table and view), use 'sys_ui_list' to lookup. If list not exists, create/insert new list object. Extract list-object's sys_id for later use (from either existing one or newly created).

- Loop through all fields, for each field:

-- lookup dictionary if list-element for this field exist, use 'sys_dictionary' to lookup

-- if field exist and list-element does not exist, then create new list-element, use GlideRecord ('sys_ui_list_element'), and insert. If field not exists, do nothing. If list-element exists, do nothing.

- wrap up the status for each step and display the result of the script. End.

 

before I read your reply I was working on something similar.

 

Here's what I do:

I define the various List categories (sys_ux_list_category) on my UX List Menu Configuration (sys_ux_list_menu_config) for that workspace. On each category I add the lists (sys_ux_list) I would like to show on workspace. Each list is assigned an existing UI View

MichaelZischeck_0-1739775976644.png

Only on the Default view for these lists I define the default columns.

I then setup a system property with JSON content where the value is the name of the Category (sys_ux_list_category)

{
  "sys_ux_list_menu_config" : "Request Management",
  "sys_ux_list_category" : "Requests"
}

Then I run this script

// this script creates default columns on ui lists
// it assumes that each category sys_ux_list_category only shows lists of the same table 
// it fetches the columns on the ui list for the ui view (Default view) defined on the ux list 
// it then creates on each other ux list for it's ui view an appropriate ui list (with the Default view ui view being the "template")
var debug = {
    "debugLevel": 1,
    "debug": true,
    "prefix": "template->"
};

try {

    // fetch config settings
    var config = gs.getProperty('prefix.createListsForCategories');
    config = JSON.parse(config);

    // fetch the category record as basis, should only be one
	// get UX List Menu Configuration
	var grUXListMenuConfiguration = new GlideRecord('sys_ux_list_menu_config');
	grUXListMenuConfiguration.addQuery('name',config.sys_ux_list_menu_config);
	grUXListMenuConfiguration.query();
	grUXListMenuConfiguration.next();
    // get the category from the JSON config (you could add multiple of course as an array)
	var grCategory = new GlideRecord('sys_ux_list_category');
	grCategory.addQuery('title', config.sys_ux_list_category);
	grCategory.addQuery('Configuration',grUXListMenuConfiguration.sys_id);
	grCategory.query();
    // as there should only be one we just .next() and work on it
	if( grCategory.next()){
		// find UX lists for that category
		var grUXList = new GlideRecord('sys_ux_list');
        // here we store the master view (Default View)
		var grMasterView = new GlideRecord('sys_ui_view');
        // here we store the master list based on Default view
		var grMasterUIList = new GlideRecord('sys_ui_list');

		grUXList.addQuery('category',grCategory.sys_id);
		grUXList.query();
		while(grUXList.next()){
			// find master (Default view)
			grMasterView.get(grUXList.view);
            // interestingly the sys_id of sys_ui_view is not a sys_id, it's "Default view"
			if( 'Default view' == grMasterView.title){ 
                // having the ux list for Default view found we search the corresponding ui list
				grMasterUIList.addQuery('view', grMasterView.sys_id);
				grMasterUIList.addQuery('table', grUXList.table);
                // this is important, as, so it seems, mostly only System Default lists have the sys_name set. All others are "empty"
				grMasterUIList.addQuery('sys_name', grUXList.table);
                // also the User is always empty on system default views
				grMasterUIList.addNullQuery('sys_user');
				grMasterUIList.query();
                // there's only one UI list for Default view with the above query
                grMasterUIList.next();
                // no need to look for further UX list connected to Default view
				break;
			}
		}
		// find all UX lists for the category we found above
		grUXList = new GlideRecord('sys_ux_list');
		grUXList.addQuery('category',grCategory.sys_id);
		grUXList.query();
		while(grUXList.next()){
            // as we do only want to set the NON Default view ui lists we exclude the UX lists which have the MasterView sys_id
			if( grUXList.view != grMasterView.sys_id){
                // get the connected UI view for that UX list 
				var grView = new GlideRecord('sys_ui_view');
				grView.get(grUXList.view);
				
                // get the appropriate ui list 
				var grList = new GlideRecord('sys_ui_list');
				grList.addQuery('name',grUXList.table);
				grList.addQuery('sys_name', grUXList.table);
				grList.addQuery('view', grView.sys_id);
				grList.query()
				while(grList.next()){
                    // delete the previous "ui list" to make sure we only have the most recent 
					grList.deleteRecord();
				}
                // create the new ui list with columns as defined in the default view for that category
                // first create the ui list record
				grList = new GlideRecord('sys_ui_list');
				grList.initialize();
				grList.setValue('name', grUXList.table);
				grList.setValue('sys_name', grUXList.table);
				grList.setValue('view', grView.sys_id);
				grList.insert();

                // then fetch the master ui list elements and "copy" them to the newly created ui list
				var grListElement = new GlideRecord('sys_ui_list_element')
				var grMasterUIListElement = new GlideRecord('sys_ui_list_element');
				grMasterUIListElement.addQuery('list_id', grMasterUIList.sys_id);
				grMasterUIListElement.query();
				while( grMasterUIListElement.next()){
					var grUIListElement = new GlideRecord('sys_ui_list_element');
					grUIListElement.initialize();
					grUIListElement.setValue('element', grMasterUIListElement.element);
					grUIListElement.setValue('position', grMasterUIListElement.position);
					grUIListElement.setValue('list_id', grList.sys_id);
					grUIListElement.insert();
				}

			}
		}

	}else{
		gs.info('category not found');
	}

} catch (e) {
    gs.info('ups, maybe need to debug the code');
}

For subsequent Categories I merely change the category in the system preference, setup the List columns for the Default view, run the code again.

 

This saves me DAYS!!!!!!! it's so daunting to create 10 lists with views and apply the proper columns.

 

Of course you could, instead of taking the "Default view" ui list as template define for each view the columns/position in the Json as well...

 

I thought: I want my users to start with some "decent" default columns and they then can change to their needs