Refreshing the dashboard reset select widget value

Hello All,

I have one select widget on the sidebar to control what is displayed in main section.
When going through the options, the main content changes accordingly. However, when I refresh the dashboard, the select value resets to the first value. Is it possible to preserve the selection on refresh?

Here is a demo code to showcase the situation:

import panel as pn
import pandas as pd

pn.extension("tabulator")

def create_report(stage):
    demo_df = pd.DataFrame(
        data={
            'Steps': [f'Step {stage}{i + 1}' for i in range(10)],
            'Actions': [f'Perform step {stage}{i + 1}' for i in range(10)],
            'Info 1': [f'Info 1 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 2': [f'Info 2 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 3': [f'Info 3 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 4': [f'Info 4 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 5': [f'Info 5 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 6': [f'Info 6 regarding step {stage}{i + 1}' for i in range(10)],
        },
        index=[i + 1 for i in range(10)]
    )

    df_table = pn.widgets.Tabulator(
        demo_df,
        layout='fit_data_table',
        header_align='center',
        text_align='center',
        selectable=False,
        theme='simple',
        show_index=False,
    )

    stage_report = pn.Column(
        f'## Report stage {stage}',
        df_table
    )

    return stage_report


select = pn.widgets.Select(name='Select stage', options=['A', 'B', 'C', 'D'])
report = pn.bind(create_report, stage=select)

template = pn.template.FastListTemplate(
    site="Staging reports",
    title="",
    theme_toggle=False,
    header_background="rgb(95,158,209)",
    sidebar=[select],
    main=[report]
)

template.servable()

For instance if I have selected stage “C” on refresh it gets to stage “A”.

Thank you!

Regards, Sorin

1 Like

Hi @sorin

If you want to persist state across sessions (refresh) you need to store the state somewhere. Panel provides a really elegant and beautiful solution for that sync location. I just :heart: it

Sync location will sync the state of your select widget with the url arguments if you add pn.state.location.sync(select, {'value': 'stage'})

import panel as pn
import pandas as pd

pn.extension("tabulator")

def create_report(stage):
    demo_df = pd.DataFrame(
        data={
            'Steps': [f'Step {stage}{i + 1}' for i in range(10)],
            'Actions': [f'Perform step {stage}{i + 1}' for i in range(10)],
            'Info 1': [f'Info 1 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 2': [f'Info 2 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 3': [f'Info 3 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 4': [f'Info 4 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 5': [f'Info 5 regarding step {stage}{i + 1}' for i in range(10)],
            'Info 6': [f'Info 6 regarding step {stage}{i + 1}' for i in range(10)],
        },
        index=[i + 1 for i in range(10)]
    )

    df_table = pn.widgets.Tabulator(
        demo_df,
        layout='fit_data_table',
        header_align='center',
        text_align='center',
        selectable=False,
        theme='simple',
        show_index=False,
    )

    stage_report = pn.Column(
        f'## Report stage {stage}',
        df_table
    )

    return stage_report


select = pn.widgets.Select(name='Select stage', options=['A', 'B', 'C', 'D'])
report = pn.bind(create_report, stage=select)

pn.state.location.sync(select, {'value': 'stage'})

template = pn.template.FastListTemplate(
    site="Staging reports",
    title="",
    theme_toggle=False,
    header_background="rgb(95,158,209)",
    sidebar=[select],
    main=[report]
)

template.servable()

This makes it possible to bookmark the specific state of your app as well as share it with colleagues, customers and friends.

1 Like

Thank you, @Marc - this worked like a charm.
I wish there would be some section in the documentation for such behavior (unless there is and I missed it).
“How to preserve widgets values/parameters” or something where concrete examples could be added. :slight_smile:

Hi @sorin . We all wish the documentation was better. @droumis is working on creating an overview of the pains and solutions.

If you have some concrete wishes please create requests on Github or even better make some PRs that helps improve the docs.

Thanks.

2 Likes

@Marc , your help and examples are being very useful across holoviz organization, thank you!
However, the solution you provided here is a bit cumbersome to be used in my case.
My application has about 20-25 variables which define it’s state. Having such a big URL would make it clunky to manage and also a bit abusing the “location” parameters.

The idea I had in mind is quite simple:

  1. User is going through auth (so I have unique ID)
  2. New session is created
  3. The values for the widgets are chosen by the user - which is triggering some rendering of some plots
  4. It also triggers some implementation which allows me to persist choices made by the user somewhere
  5. User leaves application (closing the tab/browser)
  6. Next day user visits the same URL
  7. Application identifies that it’s not the first-time usage and fetching arguments from the last choice made by the user
  8. Application set’s values for the widgets based on saved last session values - which brings user back to the place he/she left it at yesterday.

How would you implement it and is there any way to simplify it using panel functionality?