You are currently viewing the new Anvil Editor Docs.
Switch to the Classic Editor Docs
You are currently viewing the Classic Editor Docs.
Switch to the new Anvil Editor Docs

Navigation

An Anvil app is composed of Forms, and navigation is simply a matter of displaying the correct Form.

Displaying a new page

To display a new page, call open_form() (from the anvil module), and pass in the instance of the Form that you’d like to display as your new page. When you do this, the new Form takes over entirely and becomes the top-level Form. The old Form is no longer visible.

If you pass any extra parameters into open_form(), they are passed to the new Form’s constructor:

class Form1(Form1Template):
  # ...

  def btn1_click(self, **event_args):
    open_form('Form2', my_parameter="an_argument")

As well as specifying a Form by name, you can also create an instance of the Form yourself and pass it in. This code snippet is equivalent to the previous one:

from ..Form2 import Form2

class Form1(Form1Template):
  # ...

  def btn1_click(self, **event_args):
    frm = Form2(my_parameter="an_argument")
    open_form(frm)

Note that Forms are not available to other Forms unless you explicitly import them. Each Form has its own module, which has the same name as the Form, so to import Form2 from inside Form1, you use from ..Form2 import Form2.

Learn about importing Forms, Modules and Packages in Anvil

Resetting the current Form

To reset the Form that’s currently open, just run open_form(form_name). For example, if Form1 is open, run open_form("Form1").

Replacing just the main content

Oftentimes, you’ll want to build an app that has a navigation bar so that users can switch to different pages in your app. The best way to build this is by creating a Layout Form that has a Slot for the main content and a navigation bar with Links inside. You can then add Forms to your app that use the Layout Form as their Layout. The Links in the Layout Form should each have an event handler that calls open_form to switch to the desired Form.

def about_us_link_click(self, **event_args):
  """This method is called when the link is clicked"""
  open_form('AboutUs')

Because the Forms are all using the same layout, the pages in your app will have the same navigation bar.

Switching to another page in the app that has the same layout.

Switching to another page in the app that has the same layout.

Check out our tutorial on creating a multi-page app to see a worked example of using a Layout Form to navigate between pages:

You don’t have to write one click handler per Link. You can get which Link has been clicked from the event_args['sender'], so you can use that to work out which Form to instantiate.

Say, for example, your app has a Layout that contains three navigation links called home_link, about_link, and contact_link, as well as three additional Forms called ‘Home’, ‘About’ and ‘Contact’. You can set each Link’s tag attribute to the name of the Form you want to open (or an instance of that Form):

from .Home import Home
from .About import About
from .Contact import Contact

class Form1(Form1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    # set each Link's `tag.form_to_open` attribute to an instance of the Form you want to open
    self.home_link.tag.form_to_open = Home()
    self.about_link.tag.form_to_open = About()
    self.contact_link.tag.form_to_open = Contact()

Then, you can configure one click handler to use for home_link, about_link, and contact_link in your top-level Form:

  def nav_link_click(self, **event_args):
    """A generalised click handler that you can bind to any nav link."""
    # Find out which Form this Link wants to open
    open_form(event_args['sender'].tag.form_to_open)

You can then set the nav_link_click function as the ‘click’ event handler for home_link, contact_link and about_link:

Apply one click handler to all nav links

Apply one click handler to all nav links

Apply one click handler to all nav links

Apply one click handler to all nav links

Using the URL hash

get_url_hash() gets the decoded hash (the part after the ‘#’ character) of the URL used to open this app.

self.label_1.text = f"Our URL hash is: {get_url_hash()}"

You can create a URL-based navigation system by opening a particular Form depending on the URL hash:

if get_url_hash() == 'stats':
  from Stats import Stats
  self.content_panel.clear()
  self.content_panel.add_component(Stats())
elif get_url_hash() == 'analysis':
  from Analysis import Analysis
  self.content_panel.clear()
  self.content_panel.add_component(Analysis())

Query params

If the first character of the hash is a question mark (e.g. https://myapp.anvil.app/#?a=foo&b=bar) or an exclamation point followed by a question mark (e.g. https://myapp.anvil.app/#!?a=foo&b=bar), it will be interpreted as query-string-type parameters and returned as a dictionary (e.g. {'a': 'foo', 'b': 'bar'}).

get_url_hash() is available in Form code only.


Do you still have questions?

Our Community Forum is full of helpful information and Anvil experts.