I'm experimenting with using the Tree component for navigation rather than the Menu Tree. It offers the user clear visibility of where in the site they are whereas the Menu Tree doesn't.
I'm making the tree configurable within the application (subject to user roles) and want to use a simple markup structure to generate the Tree's props.items.
Markup would look like this with the syntax anchor text | page URL. The URL can be passed to the tree's onActionPerformed event to cause a navigation to the URL specified in props.selection.0.value.url.
I'm using this code in a script transform. Original binding is to a dataset containing path data. ex: "A/B/C"
items = []
for row in range(value.rowCount):
path = value.getValueAt(row, 0)
current = items
for part in path.split("/"):
# Check if the current folder exists in our items list
folderExists = False
for itemsPointerItem in current:
if part == itemsPointerItem['label']:
folderExists = True
current = itemsPointerItem['items']
if not folderExists:
item = {
"label": part,
"expanded": False,
"items": [],
"data": path,
"icon": {
'path': 'material/stop',
'color': 'red',
'style': {}
}
}
current.append(item)
current = item['items']
return items
Thank you for that. I've got your code working. If anyone wants to try it out then past the code below into an expression binding on a Tree component's props.items.
Tree component test binding code.
# Temporary test string.
value ='''A001
A001/B001
A001/B001/C001
A001/B001/C002
A001/B001/C003
A002
A002/B001
A002/B002
A003
A003/B001
A003/B001/C001
A003/B001/C002
A003/B001/C003'''
items = []
for path in value.splitlines():
current = items
for part in path.split("/"):
# Check if the current folder exists in our items list
folderExists = False
for itemsPointerItem in current:
if part == itemsPointerItem['label']:
folderExists = True
current = itemsPointerItem['items']
if not folderExists:
item = {
"label": part,
"expanded": False,
"items": [],
"data": path
}
current.append(item)
current = item['items']
return items
Create an Expression Binding on the Tree's props.items to your text.
Add a script transform on the expression binding and paste in the following code.
# Anchors and path URLs to be provided in form shown below using '|' (vertical bar) as separator.
# A001 |/Home
# A001/B001 |/Area/1/Bath/1
# A001/B001/C001 |/Area/1/Bath/1/Clamp1
items = []
for path in value.splitlines():
if path.strip(): # Check for empty lines.
current = items
branch, url = path.split('|')
for part in branch.strip().split("/"): # Strip off leading and trailing spaces.
folderExists = False # Check if the current folder exists in our items list.
for itemsPointerItem in current:
if part == itemsPointerItem['label']:
folderExists = True
current = itemsPointerItem['items']
if not folderExists:
item = {
"label": part,
"expanded": False,
"items": [],
"data": {"url": url.strip()}
}
current.append(item)
current = item['items']
return items
The result is the same as my post above.
@Matthew.gaitan, thank you for the link. It saved me many hours, I suspect. I've edited the original question to better match the solution and remove some of my woolly thinking. I've marked this answer as the "solution" as it provides the full answer to my question, but thank you very much for your help.