How to generate full name for Hierarchical object

smarti37
Kilo Sage

Hi,

I found an interesting Business Rules in ServiceNow to generate the full name for a Location.
BR : Location - generate full name


var r = new Packages.com.glide.glideobject.HierarchicalReference();
r.generate(current);


I would like to do the same thing but for a custom table to manage the classification of my tickets (I don't use "Category" field) with many levels.

I added a screenshot about what I try to do.
I tried to create a copy of the OOB Business Rules available for "Location" full name but it didn't work.

Do you think it's possible to use "Packages.com.glide.glideobject.HierarchicalReference()" for a custom field ?

Regards,
SMA.
4 REPLIES 4

erite123
Kilo Contributor

I have the same requirement.
Thanks


half_baked1
Kilo Contributor

I was doing a prototyping session and took a quick look at 'Packages.com.glide.glideobject.HierarchicalReference()' but didn't want to fiddle with it so I did the following:

1. For the reference field calling my hierarchical table, added attribute 'tree_picker=true' to the dictionary attribute
2. for the hierarchical table, added u_parent (ref to it's own table) and u_fullname
3. Added a business rule to build/set fullname (recurse up parent path to build fullname from root (top most record without parent).
4. Added a business rule to update child records if the name changes (since the fullname of all children would need to change).
5. For testing convenience, added a UI action 'Update this fullname' and 'Update all fullnames' which force the updates instead of triggering on field value change.

Works, at least to the degree I wanted for POV:
Adding children to parent updates the fullname field correctly
Updating a parent name updates children fullnames correctly
reference fields set to treepicker show expandable hierarchy

Which is pretty much what I wanted: functionality like cmn_location but for a custom table. If I could get Packages.com.glide.glideobject.HierarchicalReference() to work (or the new non-package version), I'd still prefer to use my own business rules since that gives me more places to customize.

Note: For my business rules, I used a recursive function, but just for the purposes of POV: I didn't build in loop-check so if two records pointed to each other as parents...well...er... bad things would happen:

Code for Business rule: Generate full name




current.u_full_name = getFullName(current);
current.update();


function getFullName(obj) {
//Note: This is a simple parent recursion, but needs to have a loop-breaker added!
var fn = obj.u_name;

if (obj.u_parent !='') {

//parent exists
fn = getFullName(obj.u_parent) + '/' + fn
}
return fn;

}



Code for business rule: update children full name



var gr = new GlideRecord('u_meeting_type');
gr.addQuery('u_full_name', 'CONTAINS', previous.u_name);
gr.query();

while (gr.next()) {

gr.u_full_name = getFullName(gr);
gr.update();

}


function getFullName(obj) {
//Note: This is a simple parent recursion, but needs to have a loop-breaker added!
var fn = obj.u_name;

if (obj.u_parent !='') {

//parent exists
fn = getFullName(obj.u_parent) + '/' + fn;
}
return fn;

}


** Code disclaimer: some of my code is co-written with Jim Beam, so use at your own risk!


Thank for your reply !
It's a good starting point 🙂


KathyL
Kilo Contributor

Here is my solution.



current.u_full_name = generateFullName(current, [], {});

function generateFullName(gr, names, sysIds) {
if (gr.parent.nil() || gr.sys_id in sysIds) {
names.push(gr.name);
return names.join(' / ');

} else {
names.push(gr.name);
sysIds[gr.sys_id] = true;
return generateFullName(gr.parent.getRefRecord(), names, sysIds);
}
}