The CreatorCon Call for Content is officially open! Get started here.

How to populate Content Tree component in UI Builder using data resource?

Sergey6
Tera Contributor

Hello,

I'm trying to add a content tree component to the page. This component should display a tree generated based on the table. The table has a reference key to itself.

Is there any tutorial or example  how to do this using a dynamic binding?

What kind of Data Resource can be used to retrieve data from a table and populate "Items" parameter of the Content Tree component?

Thank you.

1 ACCEPTED SOLUTION

Guido Bernuetz
Giga Guru

Hi Sergey,

I have used the content tree component already. I'm using the Data Broker Server Script (in navigator called: "Transforms". Don't be confused! ;))

You must prepare an array of object(var answer in my script) with the properties "id" and "label".

For additional hints see my article: UI Builder Component: Content Tree

Here an example to work with different tables in one tree.

find_real_file.png

the script (it's working with 4 different tables, yours should be a more simple one):

function transform(input) {
    var piID = input.productID;
    var answer = [];
    var expanded = [];
    var level = 0;
    var MAXLEVEL = 9; // maximum for recursion level

    var inventoryObj = getInventoryObj(piID);
    if (inventoryObj == null) return answer;
    var expPathm = [inventoryObj.id];
    expanded.push(expPathm);

    getchilds(piID, inventoryObj);

    answer.push(inventoryObj);

    var result = {
        titems: answer,
        exp: expanded
    };

    return result;

    function getchilds(sourceID, parentTree) {
        var childs = [];

        var grPI = new GlideRecord('sn_prd_invt_product_inventory');
        if (grPI.get(sourceID)) {
            var specObj = getSpecObj(grPI.getValue('specification'));
            if (specObj != null) {
                childs.push(specObj);
            }
        }
        getCIs(sourceID, childs);

        var gr = new GlideRecord('sn_prd_invt_product_inventory');
        gr.addQuery('parent_sold_product', sourceID);
        gr.query();
        while (gr.next()) {
            var childID = gr.getValue('sys_id');
            var inventoryObj2 = getInventoryObj(childID);
            if (level < 2) {
                var expPath = [expPathm[0], inventoryObj2.id];
                expanded.push(expPath);
            }
            if (level < MAXLEVEL && hasChildren(childID)) {
                level++;
                getchilds(childID, inventoryObj2);
                level--;
            }
            childs.push(inventoryObj2);
        }

        parentTree.children = childs;
    }

    function getInventoryObj(piID) {
        var record = null;
        var grSpec = new GlideRecord('sn_prd_invt_product_inventory');
        if (grSpec.get(piID)) {
            var specLabel = "PI: " + grSpec.getValue('name');
            record = {
                id: grSpec.getValue('sys_id') + '#sn_prd_invt_product_inventory',
                label: specLabel
            };
        }
        return record;
    }

    function getCIs(piID, childArray) {
        var ciItem = null;
        var grIBI2SP = new GlideRecord('sn_install_base_m2m_installed_product');
        grIBI2SP.addQuery('sold_product', piID);
        grIBI2SP.query();
        while (grIBI2SP.next()) {
            var grIBI = new GlideRecord('sn_install_base_item');
            if (grIBI.get(grIBI2SP.getValue('install_base_item'))) {
                ciItem = {
                    id: grIBI.getValue('configuration_item') + '#cmdb_ci',
                    label: "CI:" + grIBI.getDisplayValue('configuration_item')
                };
                childArray.push(ciItem);

            }
        }
    }

    function getSpecObj(piID) {
        var record = null;
        var grSpec = new GlideRecord('sn_prd_pm_specification');
        if (grSpec.get(piID)) {
            var clName = grSpec.getValue('sys_class_name');
            var spPrefix = "SP";
            if (clName == 'sn_prd_pm_resource_specification') {
                spPrefix = 'RS';
            } else if (clName == 'sn_prd_pm_product_specification') {
                spPrefix = 'PS';
            } else if (clName == 'sn_prd_pm_service_specification') {
                spPrefix = 'CFSS';
            }
            var specLabel = spPrefix + ': ' + grSpec.getValue('number') + " " + grSpec.getValue('name');
            record = {
                id: grSpec.getValue('sys_id') + '#' + clName,
                label: specLabel
            };
        }
        return record;
    }

    // returns number of children
    function hasChildren(sourceID) {
        var result = false;
        var gaRels = new GlideAggregate('sn_prd_invt_product_inventory');
        gaRels.addQuery('parent_sold_product', sourceID);
        gaRels.addAggregate('COUNT');
        gaRels.query();
        if (gaRels.next()) {
            var cnt = gaRels.getAggregate('COUNT');
            if (cnt > 0) {
                result = true;
            }
        }
        return result;
    }
}

The definition of the output schema:

[
	{
		"name": "tree",
		"label": "Tree Content",
		"description": "",
		"readOnly": true,
		"fieldType": {
			"titems": {
				"name": "titems",
				"label": "Array of Tree Items",
				"description": "",
				"readOnly": true,
				"fieldType": "array"
			},
			"exp": {
				"name": "exp",
				"label": "Expanded Items",
				"description": "Array of expanded items",
				"readOnly": true,
				"fieldType": "array"
			}
		}
	}
]

Data binding to the content tree:

find_real_file.png

I hope that helps you.

I am not a helpful hunter.
I will always try to give a meaningful and valid answer.

View solution in original post

6 REPLIES 6

Hi Guido,

 

I am unable to understand the basics of this component, like what and how to dynamically provide the extended items etc. could you explain in detail the content tree component?

see https://community.servicenow.com/community?id=community_article&sys_id=8c3f0e441b69d114be4955fa234bc...

 

I am not a helpful hunter.
I will always try to give a meaningful and valid answer.