Parents, and who's got them

:alarm_clock: Editor’s Note: This thread is now out of date! See the update at the bottom. –Meredydd

I am using the dashboard template with a left side column menu. I click on a menu option and I embed (add) a form into a column panel “column_panel_main”. All good.

These embedded forms invariably contain the “pseudo-datagrid” made up of a line item form embedded into a container panel for each row, and each of these line item forms handle their own onClick events. When clicked I need to show a more detailed page with options to edit data.

My problem is how to open the details page when the line item is clicked. I can of course just “open_form” but that blatts over the dashboard form which is not a desirable visual effect.

So my question is - how can I access the “column_panel_main” container on the dashboard form from within a child object of said container? I have tried various forms of referring to “parent” to no avail.

If it can’t be done, do you have a suggestion on a better way?
I am investigating hiding containers on the overview pages and showing when necessary (thus never leaving the page), but that seems a bit messy and will get unwieldy quite quickly I think, especially if lines can show different details pages depending on content - I’d have to embed one of each kind of form and have all the logic mixed up together.

Found one way.

I create Module1 and a variable in there called mainref
In the dashboard form I set Module1.mainref=self
In the subsequent forms I can then reference Module1.mainref and manipulate the screen containers from there.

Can you see any issues with that?

Hi David,

This is another great question, because it’s such a common architecture. Your subsequent solution will definitely work, and I tend to use that approach myself for top-level navigation methods. (I usually have functions so I can do something like Module1.nav("Foo"), so that each form doesn’t need to understand the exact internals of my main Dashboard form.)

For smaller scale things like clicking on line items, there are two other good approaches.

  1. [UPDATE: This is actually unnecessary. Anvil components already have a parent attribute that refers to the parent component. There is no need to do this manually.] Pass a reference to the parent form into the constructor when you create a ‘sub’ form, and store it as something like self.parent. Then you can access attributes on the parent object directly. This works, but gets a bit cumbersome if you have multiple levels of nesting.

  2. Use the Anvil component event system. This will let you do something like self.raise_event("x-clicked") in the child form, and then in the parent form you can do child_form.set_event_handler("x-clicked", self.child_click), assuming you have a method called child_click in the parent. Custom events must start "x-", but otherwise behave entirely like normal events. I now realise that this is currently badly documented, so I will make sure that gets fixed. The advantage of this method is that your child forms don’t need to understand the architecture of your whole app, they just have to raise events. This makes subsequent modifications and refactoring much easier.

Sorry for the essay, I hope that helps. Do follow up to let us know which method you chose in the end.

- Ian.

1 Like

Thanks, Ian. I shall trial them both and see.

Actually it turns out I was unaware of a new feature - please see my update to the post above.

Could have sworn I tried “parent”, but clearly not (maybe I was thrown my the autocomplete not having the parent attribute appear - unusual of me not to just try though, hey ho…)

Don’t think that will work for me in this instance because the line item is nested under panels and a couple of forms, so after self.parent.parent.parent.parent I took the view it doesn’t add much clarity :slight_smile:

Will try the event method next though, if for no other reason than it’s something new to try…

Ah yes, I’ll make sure we get that added to the Autocompleter.

Bear in mind that events in Anvil don’t bubble, so this may not be the best solution for deeply nested components either. Your top-level module approach is probably best here.

A post was split to a new topic: Slow loading - nested panels?

Update: This thread is out of date! You can now get a reference to the top-level form by calling get_open_form().

See this (newer) post for more info: