UI Builder Component: Content Tree
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/…)
- Structure of Product Model (Specifications)
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.
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:
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.
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.
https://www.servicenow.com/community/developer-articles/ui-builder-component-content-tree/ta-p/2305852