Search code examples
pythontaipy

Changing Taipy selector lov at runtime?


I am trying to change the List of Values of a Taipy selector at runtime, but I keep failing. My lov is defined as the keys of a dictionary in my application, called shapes. I define my selector like this:

tgb.selector(value="{sel_shape}", lov=list(shapes.keys()), dropdown=True, label="Shapes")

At startup, the default values are loaded correctly. However, I need to be able to change the selector lov when I manipulate the shapes dictionary at runtime. How can I achieve that?

Here's what I tried so far.

Update the shapes dictionary

Simply updating the dictionary (e.g. adding a new key shapes['new_shape'] = [1, 2, 3]) does not work, as the selector lov does not seem to be a dynamic property.

Define the lov in a state variable

I redefined the selector as tgb.selector(value="{sel_shape}", lov="{selector_lov}", dropdown=True, label="Shapes") and defined a module global variable selector_lov = shapes.keys(). Then, manipulating the shapes dictionary has no effect on the selector lov.

Reload the page

Every time I manipulate the dictionary I make sure to reload the local page (navigate(state, to="emitter", force=True)). In my top module I have:

    def on_navigate(state, page_name, params):        
        if page_name == "emitter":
            state.selector_lov = state.shapes.keys()

Still no change in the selector lov after editing shapes.


Solution

  • Try this syntax:

    tgb.selector(value="{sel_shape}", lov="{list(shapes.keys())}", dropdown=True, label="Shapes")
    

    Here is a full example:

    from taipy.gui import Gui
    import taipy.gui.builder as tgb
    
    shapes = {"Mail":["example@example", "example2@example"],
              "Person":["John Doe", "Jane Doe"]}
    
    selected_shape = None
    
    def add_shape(state):
        state.shapes["Skill"] = ["Python", "R"]
    
    with tgb.Page() as page:
        tgb.selector("{selected_shape}", lov="{list(shapes.keys())}", dropdown=True)
    
        tgb.button("Add a new shape", on_action=add_shape)
    
    Gui(page).run()
    

    You normally don't have to navigate to the page and reload it.

    You could have used a LOV variable as you mentioned:

    from taipy.gui import Gui
    import taipy.gui.builder as tgb
    
    shapes = {"Mail":["example@example", "example2@example"],
              "Person":["John Doe", "Jane Doe"]}
    
    shapes_lov = list(shapes.keys())
    
    selected_shape = None
    
    def add_shape(state):
        state.shapes["Skill"] = ["Python", "R"]
        state.shapes_lov = list(state.shapes.keys())
    
    with tgb.Page() as page:
        tgb.selector("{selected_shape}", lov="{shapes_lov}", dropdown=True)
    
        tgb.button("Add a new shape", on_action=add_shape)
    
    Gui(page).run()
    

    Also, note that usually, changes are propagated to the state when having a direct assignment. state.shapes = new_value and not by doing state.shapes["Skill"] = ["Python", "R"]. Here it is working because this kind of assignment are supported by Taipy for dictionary.