I have a very nested and rigid set of repeating panels that is supposed to work like a navigable folder/ file browser.
The nested structure is something like this:
project name 1
year 1
file 1
file n
year n
file 1
file n
project name n
.
.
.
You can see how terribly messy this is once I build a few nested repeating panels.
What I’d like to be able to do is construct such a structure programatically. This way things are more agile if the folder/file structure has to change.
I imagine being able to generate the tree by reading a dictionary that contains information about the hierarchical structure.
Has anyone tried to do something like this before, or is there a better way to go about things?
@stefano.menci@shaun This is such a silly question, but in stefano’s example the form “StaticTree” has a function in it called “form_show”. It seems to automatically get called whenever the “StaticTree” form is opened.
I have copied the app almost entirely to something I’m working on, and when I open the “StaticTree” form, “form_show” never runs.
What am I missing here? Here is my version of the “StaticTree” form, the only difference is that I’m generating the dictionary used to make the folder tree.
from anvil import *
import anvil.server
import anvil.users
import anvil.microsoft.auth
import anvil.tables as tables
from anvil.tables import app_tables
from TreeOutline import TreeOutline
from TreeData import TreeData
#from FakeDatabase import fake_data
class StaticTree(StaticTreeTemplate):
def __init__(self, folder_filter, **properties):
self.init_components(**properties)
self.nodes = {}
path = anvil.server.call('get_paths', folder_filter)
#projects=list(set([item['project'] for item in path]))
#data=[{'project': p} for p in projects]
# converting to tree form
end=[]
for d in path:
entry={"id": d["path"][0]}
entry.update({"text": d["path"][0]})
end.append(entry)
for i in range(1, len(d["path"])):
entry = {"id": ".".join(d["path"][:i+1])}
entry.update({"parent": ".".join(d["path"][:i])})
entry.update({"text": d["path"][i]})
end.append(entry)
end.append({"id": d["fname"], "parent": entry["id"], "fname": d["fname"]})
fake_data=end
def form_show (self, **event_args):
for i in fake_data:
self.add_item(i)
def add_item(self, item):
parent_id = item.get('parent')
parent_node = self.nodes[parent_id] if parent_id else None
if 'text' in item:
node = TreeOutline(item['text'], parent_node=parent_node)
else:
node = TreeData(item)
self.nodes[item['id']] = node
if parent_node:
parent_node.add_child(node)
else:
self.first_level_container.add_component(node)
If you open the form in design mode and look on the bottom right corner you will see 3 form events.
By default they are empty, which means no user function is executed when the form appears, disappears or its data binding is refreshed.
If you want to run something when the form appears, all you need to do is click on the blue arrow and Anvil will add the show_form name on the properties window and create a stub of the show_form function on the code window. You could also type a different function name, but using the standard one makes it more readable.
How did you get such a nice indentation level for your tree? When I copy what you have exactly (I assume), I get essentially no indentation. When I add a spacer to approximate what you get, the indentation is huge. I can’t see what I’m doing that is different from what you have. If you have a second, could you have a look?
Currently, trying to clone the app so you can see it, but I’ve got some authentication I have to bypass.
My example was one of the first things that I made with Anvil and was taking advantage of… the lack of control on margin and padding. You can see that the children elements in my tree have a nice indent on the left and a not so welcome one on the right. That’s the result of whatever was in the default css when I made that app.
Perhaps the default css in Anvil have changed and the margin/padding for that element on a new app created today is zero.
I tried to clone your app, but I wasn’t able to see the tree. Perhaps there was too much stripping down.
You can try to play with the css, perhaps creating a role that adds some margin on the left.
I think that using spacers should work too. You can try by holding the ctrl button while dragging the spacer size. This should give you finer control on its width. Or, as a last resort, you could try setting its width from the code.
Hmm, I was afraid that it was a CSS thing that may have changed since the app was created. The clone works for me but I should have mentioned that you have to click on the initial folder to see the tree.
I shrunk the spacer as much as I could, and the indentation was as it was above. But perhaps doing that in code will allow me to shrink it more.
Thanks very much for the feedback. Much appreciated. I will try the suggestions.