St.selectbox not working in st.form

I was trying to use st.selectbox in a form (st.form) but the selectbox widget was not behaving properly.

For example in the the code:

with st.form("join_form", clear_on_submit=False):
    st.subheader("Basic information")

country = st.selectbox("Country *",ctry_codes,key="ctr_sel")
cnt_code = country.split('(')[1].split(')')[0]
         
state_list =  get_states_of_country(cnt_code)
state = st.selectbox("State *",state_list)
submitted = st.form_submit_button("Join", type="primary", use_container_width=True)


The country variable is always set to ctry_codes[0].
What am I doing wrong?

Sudipta

Welcome to the community, Sudipta! Thanks for sharing your question and code snippet—this is a common point of confusion with Streamlit forms. :blush:

The issue is that widgets inside an st.form only send their values to the backend when the form is submitted. This means that dependent widgets (like your state selectbox, which depends on the country selectbox) won’t update in real time as you change the country selection—they’ll only update after you hit the submit button. As a result, country always defaults to the first option until the form is submitted, and the state selectbox doesn’t update dynamically. This is expected behavior for forms in Streamlit, as described in the Streamlit forms documentation and confirmed by community discussions (example).

If you want the state selectbox to update immediately when the country changes, you need to move the country selectbox outside the form, so its value is available to update the state options before the form is submitted.

Sources: