Ejemplo n.º 1
0
def open_form(form_name, full_width=False):
    """Use classic routing to open a registered form"""
    form = get_form(form_name)
    _title_label.text = _forms[form_name]["title"]
    get_open_form().content_panel.clear()
    get_open_form().content_panel.add_component(form,
                                                full_width_row=full_width)
Ejemplo n.º 2
0
def load_template(url_hash):
    global _current_form
    form = get_open_form()
    current_cls = type(form)
    if form is not None and current_cls not in _templates:
        raise NavigationExit  # not using templates

    logger.debug("Checking routing templates")
    for cls, path, condition in chain.from_iterable(
            _ordered_templates.values()):
        if not url_hash.startswith(path):
            continue
        if condition is None:
            break
        elif condition():
            break
    else:
        load_error_or_raise(f"No template for {url_hash!r}")
    if current_cls is cls:
        logger.debug(f"{cls.__name__!r} routing template unchanged")
    else:
        logger.debug(
            f"{current_cls.__name__!r} routing template changed to {cls.__name__!r}, exiting this navigation call"
        )
        _current_form = None
        f = cls()
        logger.debug(f"form template loaded {cls.__name__!r}, re-navigating")
        open_form(f)
        raise NavigationExit
Ejemplo n.º 3
0
    def on_navigation(self, url_hash=None, url_pattern=None, url_dict=None, path=None, dynamic_vars=None):
      # when there is navigation - back/forward navigation
      # or when the user changes the url_hash or when you call anvil.set_url_hash in code
      
      # calls the current_form's before_unload method
      # calls the MainForm's on_navigation method
      # get's the form to load (loads the error_form if there is no form to load)
      # loads the form

      global _on_navigation_stack_depth
      if _on_navigation_stack_depth > 5:
        logger.print('**WARNING**  \nurl_hash redirected too many times without a form load, getting out\ntry setting redirect=False')
        return  # could change this to a raise
      _on_navigation_stack_depth += 1

      if getattr(_current_form,'before_unload', None): 
        logger.print(f'{_current_form.__name__} before_unload called')
        """
        # before_unload in the form to be unloaded will be called here if the method exists
        # Mostly useful to prevent unloading the current form
        # it's not perfect so use with caution!!!
        # if you don't need to prevent a form from unloading ...but ...
        # ... do need to do something when the form is hidden use the form_hide event instead
        # To stop_unload return a value from the before_unload method
        """
        _anvil.js.call_js('setUnloadPopStateBehaviour',True)
        stop_unload = _current_form.before_unload()    
        if stop_unload:
          logger.print(f"stop unload called from {_current_form.__name__}")
          _anvil.js.call_js('stopUnload')
          _on_navigation_stack_depth -= 1
          return   #this will stop the navigation
        _anvil.js.call_js('setUnloadPopStateBehaviour',False)
      
      if not (url_hash and url_pattern and url_dict):
        url_hash, url_pattern, url_dict = get_url_components()
      logger.print(f"on_navigation triggerd\nurl_hash    = {url_hash}\nurl_pattern = {url_pattern}\nurl_dict    = {url_dict}")
      
      if getattr(Cls,'on_navigation', None): 
        logger.print(f'{Cls.__name__} on_navigation called')
        # on_navigation in your main form will be called here
        # in the example we change 'selected' role on links using this method
        Cls.on_navigation(self, url_hash=url_hash, url_pattern=url_pattern, url_dict=url_dict, unload_form=_current_form)    

      try:
        if url_hash not in _cache and path is None:
          path, dynamic_vars = self.find_path(url_hash, url_pattern, url_dict)
      except KeyError:
        logger.print(f'no route form with url_pattern={url_pattern} and url_keys={url_dict.keys()}')
        if _error_form is not None:
          load_error_form()
        elif _anvil.get_open_form(): # raising an exception before there is an open form stops anything loading
          raise # if you can't work out why your page won't load then take raise out of this if block...
      except:
        raise  # this was an unexpected error so raise it
      else:
        self.content_panel.clear()  # clear the form now just incase we end up with a new to cache form that is slow to load later
        self.load_form(url_hash=url_hash, url_pattern=url_pattern, url_dict=url_dict, path=path, dynamic_vars=dynamic_vars)
      
      _on_navigation_stack_depth -= 1
Ejemplo n.º 4
0
def add_form_to_container(form):
    if form.parent:
        # I may have been used within another template so remove me from my parent
        form.remove_from_parent()
    layout_props = getattr(form, "_routing_props", {}).get("layout_props", {})
    cp = get_open_form().content_panel
    cp.clear()  # clear it again
    cp.add_component(form, **layout_props)
Ejemplo n.º 5
0
 def fire_show_event(e):
     if component is None:
         return
     open_form = _anvil.get_open_form()
     if open_form is not None and fake_container.parent is None:
         open_form.add_component(fake_container)
     if component.parent is None:
         # we add the component to a Container component
         # this doesn't really add it to the dom
         # it just allows us to use anvil's underlying show hide architecture
         fake_container.add_component(component)
Ejemplo n.º 6
0
def load_template_or_redirect(url_hash):
    global _current_form
    form = get_open_form()
    current_cls = type(form)
    if form is not None and current_cls not in _templates:
        raise NavigationExit  # not using templates

    logger.debug("checking templates and redirects")
    for info in chain.from_iterable(_ordered_info.values()):
        callable_, paths, condition = info
        try:
            path = next(path for path in paths if url_hash.startswith(path))
        except StopIteration:
            continue
        if condition is None:
            break
        elif not condition():
            continue
        elif type(info) is TemplateInfo:
            break
        redirect_hash = callable_()
        if isinstance(redirect_hash, str):
            if navigation_context.matches_current_context(redirect_hash):
                # would cause an infinite loop
                logger.debug("redirect returned current url_hash, ignoring")
                continue

            from . import set_url_hash

            logger.debug(f"redirecting to url_hash: {redirect_hash!r}")

            set_url_hash(
                redirect_hash,
                set_in_history=False,
                redirect=True,
                replace_current_url=True,
            )
        navigation_context.check_stale()

    else:
        load_error_or_raise(f"no template for url_hash={url_hash!r}")
    if current_cls is callable_:
        logger.debug(f"unchanged template: {callable_.__name__!r}")
        return info, path
    else:
        msg = f"changing template: {current_cls.__name__!r} -> {callable_.__name__!r}"
        logger.debug(msg)
        _current_form = None
        # mark context as stale so that this context is no longer considered the current context
        navigation_context.mark_all_stale()
        f = callable_()
        logger.debug(f"loaded template: {callable_.__name__!r}, re-navigating")
        open_form(f)
        raise NavigationExit
Ejemplo n.º 7
0
def load_error_form():
    global _error_form, _current_form
    logger.debug(f"loading error form: {_error_form!r}")
    url_hash, _, _ = get_url_components()
    _cache[url_hash] = _error_form()
    _current_form = _cache[url_hash]
    f = get_open_form()
    if f is not None:
        add_form_to_container(_current_form)
    else:
        open_form(_current_form
                  )  # just in case we somehow don't have a valid template!
Ejemplo n.º 8
0
def alert_form_loaded(**url_args):
    f = get_open_form()
    on_form_load = getattr(f, "on_form_load", None)
    if on_form_load is not None:
        logger.debug(f"{f.__class__.__name__}.on_form_load() called")
        on_form_load(**url_args)
Ejemplo n.º 9
0
def clear_container():
    get_open_form().content_panel.clear()
Ejemplo n.º 10
0
def alert_on_navigation(**url_args):
    f = get_open_form()
    on_navigation = getattr(f, "on_navigation", None)
    if on_navigation is not None:
        logger.debug(f"{f.__class__.__name__}.on_navigation() called")
        on_navigation(unload_form=_current_form, **url_args)
Ejemplo n.º 11
0
def _update_key(key):
    if type(key) is str:
        key = (key, type(get_open_form()).__name__)
    return key