Persist state of form when navigating away from it

Calling the CalendarContainer each time is the problem here.
Really you want to cache that Form so that you always load the same form… this way it persists across navigation changes.

A simple fix is to define attributes.

class Startup(StartupTemplate):
  def __init__(self, **properties):
    self.init_components(**properties)
    self.calendar_form = None
    self.main_form = None

  def button_calendar_click(self, **event_args):
    self.calendar_form = self.calendar_form or CalendarContainer()
    self.content_panel.clear()
    self.content_panel.add_component(self.calendar_form)

This way you only create a single instance of the CalendarContainer and next time the button is clicked it loads the cached form.

You can adjust the code be more DRY, and even take advantage of functools.cache

e.g.

import functools
from ..MainForm import MainForm
from ..CalendarContainer import CalendarContainer

class Startup(StartupTemplate):
  def __init__(self, **properties):
    self.init_components(**properties)
    self.tag_to_form = {"main": MainForm, "calendar": CalendarContainer}
    self.button_cal.tag = "calendar"
    self.button_main.tag = "main"
  
  @functools.cache
  def get_form(self, tag):
    """return the cached form or creates a new one if not in the cache"""
    return self.tag_to_form[tag]()

  def nav_button_click(self, sender, **event_args):
    form = self.get_form(sender.tag)
    self.content_panel.clear()
    self.content_panel.add_component(form)

Another option is to use the hash routing module.
This caches the forms so you don’t have to.

from anvil_extras import routing
from ..MainForm import MainForm
from ..CalendarContainer import CalendarContainer

@routing.main_router
class Startup(StartupTemplate):
  def __init__(self, **properties):
    self.init_components(**properties)
    self.button_cal.tag = "calendar"
    self.button_main.tag = ""

  def nav_button_click(self, sender, **event_args):
    # loads a cached form or creates a new one based on the url_hash
    routing.set_url_hash(sender.tag)

---

# In the calendar form
@routing.route("calendar")
class CalendarContainer():
    ...

---

# In the MainForm
@routing.route("")
class MainForm():
    ...

And then there’s the anvil_extras navigation module which is worth exploring to help with navigation techniques.

5 Likes