Stuck trying to use parenting from a repeating panel

Hello everyone. I am very new to Python and Anvil as I come from a js background. Therefore, my problems are due to a lack of my own knowledge rather than anything else. I must say that Python and Anvil are a bit of a revelation to me to be honest - I am loving it so far.

Anyway, to my issue. I have set up a structure as follows:

  1. I have a form called “base” that has my top and side nav on it. Within “base” I have a content-panel.

  2. I have several other forms that are essentially just columns/cards ready for placement into the “base” content-panel.

  3. I replace the “base” content-panel with whichever form/page I need (this is how I produce a multipage website) using things like:

  def lk_dashboard_click(self, **event_args):
    self.content_panel.clear()
    self.content_panel.add_component(dashboard())
  1. One of my forms is a repeating panel that for each instance populates a button with a serial number that is pulled from data I have from a json. This serial number is read from the button and placed in a global variable so that I can get at it later, from anywhere.

  2. The repeating panel lives in a simple form (for placement into the “base” content-panel). This form is called “show_all”. Therefore, the structure is that show_all is the parent and ItemTemplate1 is the child of show_all, just as it makes it when you drag the repeating_panel component into the page.

My problem:
What I want to do once the button is clicked is clear the whole panel and replace it with the form “show_user”, which is also a simple column/card that sits inside the content-panel. The problem I am having is that I cannot figure out how to do this because my “self” is the repeating panel and I do not understand the parenting. In essence I need to be accessing “base” from here because that is where the content-panel lives, and then clear and replace the current content-panel’s contents (which right now is show_all + ItemTemplate1) with show_user. Effectively at this stage of button click I am completely finished with show_all/ItemTemplate1 and wish to discard/clear it and display show_user in the content_panel of “base”.

ChatGPT has sent me around in circles for a day trying parent.parent.parent, and all manner of other things, but I think it is my understanding that is flawed, and ChatGPT doesn’t really have enough info about Anvil to make sensible suggestions.

I tried things like:

open_form(base)
self.content_panel.clear()
self.content_panel.add_component(show_user())

… but that doesn’t work because I believe it still thinks it’s on the repeating_panel form at this stage.

What I’m trying to do is all very straightforward. (I am not using layouts because in all honesty I did not know about them at the time :slightly_smiling_face:

The issues are mine, and in me being very new to this. Back in js I would just hit the dom directly, but because of my green status I’m not sure if I my lack of understanding is with Anvil or Python.

I hope someone can shed some light for me.

Thank you.

can you share a clone that shows the problem (it can be a stripped down version)? it’s hard to say since there’s a lot of specifics we can’t see here.

What you need is the get_open_form function. It returns the instance of the top-level form that is currently open (in your case base).

So you can do something like:

def button_click(self, **event_args):
  base_form = get_open_form()
  base_form.content_panel.clear()
  base_form.content_panel.add_component(show_user())

The get_open_form function is part of the base anvil module. You can import it like this:

from anvil import get_open_form

or if you do from anvil import * it will already be imported for you.

Thank you both very much for your reply.

@duncan_richards12
At this stage I’m not sure I am able to share the project because the json has external client data that is being pulled in via an api. I will check on this because it may certainly help to share it.

@Zaro
Thank you, this all makes good sense and I’ve tried it but still have an issue, although I really feel the right track is on now. FYI I am doing a from anvil import * but I have also tried adding from anvil import get_open_form to ItemTemplate1 too. This is what I have:

  def btn_stb_mac_click(self, **event_args):
    globals.current_mac=self.btn_stb_mac.text
    base_form = get_open_form()
    base_form.content_panel.clear()
    base_form.content_panel.add_component(show_user())

The error I get is:

NameError: name 'show_user' is not defined

  • at show_all.ItemTemplate1, line 31

…and I also have a squiggly line under base_form.content_panel.add_component(show_user()) denoting that it is undefined.

I tried adding from ..show_user import show_user to ItemTemplate1 but when I do I get the error ModuleNotFoundError: No module named 'show_user'

Any help greatly appreciated.

Thank you.

This is likely the part that’s going wrong.

As your ItemTemplate1 is nested within the repeating panel, it is one level deeper in the project structure. So you need to go one level higher when importing show_user:

from ...show_user import show_user

Or perhaps even one level higher depending on where you copied the original import from:

from ....show_user import show_user

Try relying on Anvil’s autocomplete. Simply type from . in your code and see what the autocomplete suggestions are. Those can be very handy and time-saving.

@Zaro
Thank you very much Sir!
Yes indeed that was it… the parent I was targetting was three dots up, and that suggestion of using the autocomplete to seek things out was superb.

I learn a little more every day.

Thanks again to both of you for offering to help, and thank you Zaro for the solution.

1 Like