Guido Bernuetz
Giga Guru

ServiceNow documentation: https://developer.servicenow.com/dev.do#!/reference/now-experience/sandiego/now-components/now-content-tree/overview

Use Cases

The Content Tree is a powerful widget to make complex data structures transparent.

Examples of use cases:

  • SAFe: Structure of Epics/Stories/Tasks
  • PPM: Structure of Programs/Projects/Subprojects/Project Tasks
  • TSM/OMT:
    • Structure of Product Model (Specifications)
    • Customer Order/Order Line Items/Domain Orders/Tasks
    • Structure of Product Inventory (Parent/Child/Child of Child/…)

The main properties of tree items are the internal id and the visible label. Both are simple strings!

Scrolling is supported when the tree component has a fixed height otherwise it will be always longer.

Based on the selected item different components can be displayed on the same page.

Example script to identify and manage different types of items:

/**
 * @param {params} params
 * @param {api} params.api
 * @param {any} params.event
 * @param {any} params.imports
 * @param {ApiHelpers} params.helpers
 */
function handler({
    api,
    event,
    helpers,
    imports
}) {
    var treeID = api.state.selectedTreeItem;
    var ids = treeID.split('#');
    api.setState('selectedID', ids[0]);
    api.setState('selectedType', ids[1]);
    api.setState('detailsURL', "/nav_to.do?uri=" + ids[1] + ".do?sys_id=" + ids[0]);
    if (ids[1] == 'sn_ind_tmt_orm_order_task') {
        api.setState('isTask', true);
        api.setState('isOLI', false);
        api.setState('isSpec', false);
        api.setState('isProductOrder', false);
    } else if (ids[1] == 'sn_ind_tmt_orm_order_line_item') {
        api.setState('isTask', false);
        api.setState('isOLI', true);
        api.setState('isSpec', false);
        api.setState('isProductOrder', false);
    } else if (ids[1] == 'sn_prd_pm_product_specification') {
        api.setState('isTask', false);
        api.setState('isOLI', false);
        api.setState('isSpec', true);
        api.setState('isProductOrder', false);
    } else if (ids[1] == 'sn_ind_tmt_orm_product_order' || ids[1] == 'sn_ind_tmt_orm_service_order') {
        api.setState('isTask', false);
        api.setState('isOLI', false);
        api.setState('isSpec', false);
        api.setState('isProductOrder', true);
    }
}

Controlling of expanded/collapsed areas

You must specify the item path as an array to define expanded items.

Path means an array of parent id’s starting from the top-most one.

Example:

[
    [
      "3ee1fdb1c3331010d216b5183c40dd81"
    ],
    [
      "3ee1fdb1c3331010d216b5183c40dd81", "af66e551c32f10105252716b7d40dd52"
    ],
    [
      "3ee1fdb1c3331010d216b5183c40dd81", "fbd9e5a7c32310105252716b7d40ddb7"
    ]
  ]

Access an item after selection

Grab a single item selection by event “Content tree item clicked”. The id is available by @payload.item.id

Expand and collapse all items

It’s often very helpful to have some buttons to expand and collapse all items.

To change the expanded items by a script and manually in the content tree you must bind the “Expanded Items” property to a client state parameter.

find_real_file.png

Expand all items

To expand all items, walk through the complete item tree and fill the array with the path of ids of each item.

Example script to walk through all items delivered by the data broker for the content tree:

/**
* @param {params} params
* @param {api} params.api
* @param {any} params.event
* @param {any} params.imports
* @param {ApiHelpers} params.helpers
*/
function handler({api, event, helpers, imports}) {
       var titems = api.data.order_tree_data.output.items;
    var sel = [];

    for (var ind = 0; ind < titems.length; ind++) {
        var spath = [];
        var titem = titems[ind];
        processID(titem);
    }
    api.setState('expandedItems', sel);

    function processID(titem) {
        spath.push(titem.id);
        var mspath = Array.from(spath);
        sel.push(mspath);
        if (titem.children != null && titem.children.length > 0) {
            for (var ind2 = 0; ind2 < titem.children.length; ind2++) {
                var ctitem = titem.children[ind2];
                processID(ctitem); // Recursion!!
            }
        }
        spath.pop();
    }
}

Assign the client script to a button:

find_real_file.png

Collapse all items

This is very easy. Set the “Expanded Items” property or the bound client state parameter to an empty array.

/**
* @param {params} params
* @param {api} params.api
* @param {any} params.event
* @param {any} params.imports
* @param {ApiHelpers} params.helpers
*/
function handler({api, event, helpers, imports}) {
    api.setState('expandedItems', []);
}

Select multiple items

The content tree is also supporting multiple selection.

find_real_file.png

You must set the property “Selected Items” in the same format as for expanded items to select multiple items by a script. Means as an array of item paths. See above for an example.

Comments
kellyf1
Tera Contributor

Is there a way to create the paths to expanded fields programmatically? We would like a category to be expanded automatically when the search term is found in that category. New developer here,

Guido Bernuetz
Giga Guru

yes, of cores. You must deliver the JSON of all expanded paths by a data broker or by a client script and set this to a state value where the specific tree attribute is pointing to.

ankit-kumar-528
Tera Contributor

Hi @Guido Bernuetz,

 

Could you please tell us the step by step configuration of this content tree component. Our requirement is to use the content tree for related list like service operation workspace SNC Record page related list.

Sharique Azim
Mega Sage

My content tree is not populating even when my data resource is returning a bindable json array.  any idea what is going wrong for me.  Please also refer 
Not able to display the content tree in UI builder, even when my transform data resource is correct 

Version history
Last update:
‎08-21-2022 08:54 AM
Updated by: