Dynamic set of selectbox widgets based on button funcrtion

Summary

Hi,
I would like to have two columns.
One column with text and button and the second column contains set of selectbox widgets.
Once clicking on the button the set of selectbox is created (dynamic number of widgets).
I tried to implement it straight forward by adding the selectbox under the button selection however it make the selectbox to disappear once selecting an option

Steps to reproduce

Code snippet:

def build_col2(calibration_properties):
    with col2:
        st.markdown("Which attributes you would like to use for calibration?")
        option = {}
        for calibration_property in calibration_properties:
            option[calibration_property["property_name"]] = st.selectbox(
                calibration_property["property_name"],
                calibration_property["property_options"],
                label_visibility=st.session_state.visibility,
                disabled=st.session_state.disabled,
            )
            if "property_name" in calibration_property:
                st.write('You selected:', option[calibration_property["property_name"]])

        if st.button("Calibrate", type="primary"):
            print("You selected")

if st.button("Prepare calibration", type="primary"):
    calibration_properties = handle_build_calibration_properties(user_question)
    print("calibration_properties " + str(calibration_properties[0]))
    build_col2(calibration_properties)

Expected behavior:

Selectbox list is being updated and fully functional

Actual behavior:

Selectedbox is updated however once selecting an element the selectbox is disappering

Debug info

  • Streamlit, version 1.26.0
  • Python 3.11.4
  • Using Conda? PipEnv? PyEnv? Pex? No
  • OS version: MaxOS
  • Browser version: Chrome

thank you

HI @Moshe,

When the second selection happens and the app re-runs the button event is no longer present. You can use a session_state variable and a callback function on the button, using the on_click attribute to control the behavior and persist the state of the app. You can check this article for more:

Best Regards,

–Carlos

1 Like

Thanks @CarlosSerrano this is really helpful.
I managed to update selectbox content based on button clicks.

import streamlit as st

st.title('Counter Example using Callbacks with kwargs')
if 'count' not in st.session_state:
    st.session_state.count = 0

def increment_counter(increment_value=0):
    st.session_state.count += increment_value

def decrement_counter(decrement_value=0):
    st.session_state.count -= decrement_value

st.button('Increment', on_click=increment_counter,
    kwargs=dict(increment_value=5))

st.button('Decrement', on_click=decrement_counter,
    kwargs=dict(decrement_value=1))
st.write('Count = ', st.session_state.count)

st.selectbox(f"Select option for '{st.session_state.count}':", ["Option " + str(st.session_state.count), "Option " + str(st.session_state.count+1), "Option " + str(st.session_state.count+2)], key=st.session_state.count)


However what if I want the the number of selectbox widgets will be dynamic. How I can remove or add selectbox dynamically based on the state (button click)

Hey @Moshe ,

I think this article from my medium will help you.

Let me know.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.