I have a use case where a list of options for a selectbox is determined by other choices they have made before. The base list is always the same, but is filtered depending on the other inputs.
My problem is every time the filtered list changes, the input jumps back to the default index.
Searching, I found another user with a similar issue but no reply:
I tried working around it by using format_func so that filtered elements get a different name, but the behavior still persists.
Looking into code for selectbox (1.31.1):
id = compute_widget_id(
"selectbox",
user_key=key,
label=label,
options=[str(format_func(option)) for option in opt],
index=index,
key=key,
help=help,
placeholder=placeholder,
form_id=current_form_id(self.dg),
page=ctx.page_script_hash if ctx else None,
)
So it seems the widget id changes every time the transformed options list changes, which is probably the cause for the unexpected behavior.
Is there a good reason why options list is part of id generation?
And if so, does it have to use the transformed list (because not doing so would at least make the workaround work).
In my use case, that would not be an issue, but I see what you mean.
How dangerous would it be to jump it back to the placeholder in that situation though?
Also - this is not the case when format_func changes, as underlying values list then remains the same.
Widgets change their value either by user interaction or by the code setting its key in session state. In this case we would have a widget magically changing its value, which doesnāt look right.
Now, all this sounds quite reasonable to me, but somehow it seems to make unreasonably hard doing what you are trying to do (and I donāt think that the format_function hack is a proper solution even if it worked). I will try to find a way later today.
this is not the case when format_func changes, as underlying values list then remains the same
I understand why immutable representations of the options are preferable, but I donāt know why the format function should be involved. Maybe it makes handling some corner cases easier (and other harder, of course).
Thank you @Goyo
Just in case you do not find a good solution, there is a (cumbersome) workaround by persisting the state yourself and just passing it as the default for cases where option list changes:
if 'choice_key' in st.session_state:
if st.session_state['choice_key'] not in option_list: st.session_state['choice_key']='default'
c_ind = plot_list.index(st.session_state['choice_key'])
else: c_ind = 0
pt = st.session_state['choice_key'] = st.selectbox(
'Choice', option_list, index=c_ind)
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking āAccept allā, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.