Designator to find attribute with value up the hierarchy

Is there a way to get the value of an attribute up the hierarchy of a note from the first note where the value has been set (!="")?
I tried:

function getTheAttribute(parentLevel){
	if($AnAttribute(parentLevel)){
		return $AnAttribute(parentLevel);
	} else {
		return getTheAttribute(parent);
	};
}

calling $Text = getTheAttribute(this); is OK if there is a local value for the attribute. If not it crashes TBX. It’s an infinit loop because parent always has the same value. My fault. I need a designator to step up the hierarchy… if this will not work, I will use the $Path.

this works:

function getTheAttribute(currentPath){
	if($AnAttribute(currentPath)){
		return $AnAttribute(currentPath);
	} else {
		$MyString = currentPath.replace("/[^/]*$",""); 
		// return $MyString;
		if($MyString==""){
			return "";
		} else {
			return getTheAttribute($MyString);
		};
	};
}

Have you looked at group designators such as ancestors? It is a list of the paths of all the ancestors—back to root level—of the current note.

$MyList = collect(ancestors,$Path); // you could collect any attribute value!

If you use ancestors in a find() you are effectively testing a list of paths of the designated note’s ancestors (default scope is this, i.e. the current note).

If you have a list of ancestors you can iterate list and test each one’s value of $AnAttribute. But, I’m a bit unclear as to the exact test condition:

  • any/all ancestor has a particular value of $AnAttribute.
  • any/all ancestor has any non-default value of $AnAttribute (i.e. a local value for that attribute)
  • … something else?

In the above bear in mind you need to consider a non-default/non-empty value might be inherited (e.g. via a prototype) as opposed to being locally set.

It might help to transpose the general problem to a specific case. If not private data, what is the problem being solved here.

Hi Mark,

at least to top ancestor should (!) have a value. The first filled attribute up the hierarchy should be returned. The value of the first ancestor may be different from the ancestor at root level and I need the value of this nearest note up the tree. It doesn’t matter if there is a pre-filled value from a prototype. If the value has been changed then I need the one in the nearest node of the tree - however it found the way into this note.

I really liked the demo from Michael with the auto-linking by keywords but I try to find a way around the prefixes. I have two containers with the same name but for different faculties. So I check for an attribute called $faculty and this may be empty at the lower levels but I still need the information to create a link to the right container.

1 Like

I might try something like this:

collect__if(ancestors,$MyNumber!=0,$MyNumber).first

1 Like

$Text = collect_if(ancestors,$Faculty!="",$Faculty).first

works 1:1 like my function - one line instead 12 :wink: