Using add_component from the Home page for another form

What I’m trying to do:
I am trying to add a component to another form from my home page when a button is clicked (the button is on the home page).

What I’ve tried and what’s not working:
I’ve tried initializing the class in the other form and then calling the add_component method.

It works if I create a button on the ResponseView form instead and then use add_component. So in the meantime, I moved the button the ResponseView form. However, I would like to know why I can’t have a button on the home page and then initialize the class from ResponseView and then call the add_component method.

I’m new to Anvil so this probably is a newbie question. I will just create the button on the ResponseView page for now, but I am still very curious why this doesn’t work. Thanks for your help!

Code Sample:

This code is in my Home form and it doesn’t work :confused:

from ._anvil_designer import HomeTemplate
from anvil import *
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import anvil.server
from .ResponseView import ResponseView

class Home(HomeTemplate):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)

  def button_show_tables_click(self, **event_args):
    """This method is called when the button is clicked"""
    response_view = ResponseView()
    label = Label()
    label.text = 'hi'
    
    response_view.add_component(label)

Solution
The issue was I had repeating panel that I was trying to add a table to if a user clicked a button after some data had already been generated. I was trying to do that using ‘add_component’ on the ResponseView Form, however, that doesn’t work since I need to add it to the current Home page Form somehow.

The solution was I needed to either add the table as a row in my data table or just add a ColumnPanel on the Home page and add a component to that. Thanks @p.colbert for helping me understand the nuance here!

This creates a local variable, response_view, as an instance of class ResponseView, and adds a Label to that instance. But since this is a local variable, at the end of the function, response_view (and the Form instance that it points at) will be destroyed without ever having been shown.

What do you want to do with that instance of ResponseView?

Ok, I think I’m following

For this case, it would just be to add a label that says ‘hi’ and show it. In reality I’m adding a data grid, but chose label in this case as a simple example.

And thanks for the quick response!

Replacing the current form?

I would want to take the current form and just add this at the bottom of it. Not sure if that means I have to replace the current form

That would be self.add_component(response_view). By attaching the Form object to self, the object

  1. is displayed at the end of self (which happens to be the current form at this time)
  2. remains “alive”. Even though the local variable response_view goes away at the end of the function, the object (form) it points to remains “alive” as long as some object is referring to it, in this case, the current form.
1 Like

Thanks, that makes sense. So that means I have a local instance of ResponseView, however, this is not the same as modifying the ResponseView instance that is returned elsewhere in my code. That makes sense to me.

The form I’m adding is inside a repeating panel on the home page so it’s slightly more nuanced. I’m trying to see how I can get it inside the repeating panel, but this is helping me understand it better for sure

A repeating panel is wired to create its own instances (of its row-template form) on demand, using the row-template’s __init__ function and its event-handlers. So, if you have any code that sets up additional per-instance widgets, that code usually goes into the row-template class.

For additional questions, though, you should probably start a new Topic.

1 Like

@p.colbert Thanks, yeah you totally helped me realize where I was going wrong here :sweat_smile: I needed to realize that I’m not accessing the already instantiated object and that the instantiation has already occurred for the repeating panel. I need to reload the repeating panel with the added item if I want it to show it on the home page.

I edited my initial post with some more detail on what I did for the solution and marked your reply as the solution. Thanks for helping me wrap my head around this!

1 Like

Or ask the existing repeating-panel’s list of objects to update themselves in situ.

True, I’ll have to play around with it to get more comfortable