Dynamic UI based on selectbox choose in form

Hi, I am in the process of developing an application that contains a “Settings” page. In it, I have a form with many fields (mainly text_input and selectbox). Depending on the selected option in the selectbox, I would like to display other things in the user interface. However, the selectbox in the form does not refresh my interface (this is the correct behavior according to the documentation). However, I would like to ask how I could achieve this.
Below is an example of simplified code:

import streamlit as st

# AI Section
form = st.form('ai_form')

type_of_something = form.selectbox('Type of something', CourtCaseType.get_all())

if SomethingType.get_by_name(type_of_something) == SomethingType.X:
    left, right = form.columns(2)
    with left.container(border=True):
        first_provider = st.selectbox('provider', Providers.get_all())
        first_model = st.selectbox('model', Models.get_all_by_provider(first_provider))
    with right.container(border=True):
        second_provider = st.selectbox('provider', Providers.get_all())
        second_model = st.selectbox('Model', Models.get_all_by_provider(second_provider))

else:
    left, right = form.columns(2)
    with left.container(border=True):
        first_provider = st.selectbox('provider', Providers.get_all())
        first_model = st.selectbox('model', Models.get_all_by_provider(first_provider))
    with right.container(border=True):
        second_provider = st.selectbox('provider', Providers.get_all())
        second_model = st.selectbox('model', Models.get_all_by_provider(second_provider))

# Form Submit
with form.columns([3, 3, 1])[2]:
    submitted = st.form_submit_button('Submit')

if submitted:
    pass

I looked for a solution in the documentation and on the forum, but I don’t think I found anything that addresses such a case.
For any suggestions and answers I will be grateful :blush:

@ceziklikewhat I have the same issue. Did you ever get this to work?

I wasn’t able to get st.form to function in desired way, but I was able to recreate something identical using st.container instead:

import streamlit as st

# Create form using container instead 
with st.container(border=True):
    type_of_something = st.selectbox('Type of something', ['type1','type2'])
    
    # precreate columns within container (c_NULL is blank space column, can be removed )
    left,right,c_NULL = st.columns([3, 3, 1])
    if type_of_something == 'type1':
        with left.container(border=True):
            first_provider = st.selectbox('provider1', ['option1','option2'])
            first_model = st.selectbox('model1', ['option1','option2'])
        with right.container(border=True):
            second_provider = st.selectbox('provider2', ['option1','option2'])
            second_model = st.selectbox('Model2', ['option1','option2'])
    else:
        with left.container(border=True):
            first_provider = st.selectbox('provider3', ['option1','option2'])
            first_model = st.selectbox('model3', ['option1','option2'])
        with right.container(border=True):
            second_provider = st.selectbox('provider4', ['option1','option2'])
            second_model = st.selectbox('model4', ['option1','option2'])
    
    submitted = st.button('Submit')

if submitted:
    # Record form results here 
    pass

My understanding is that what you are experiencing with st.form is by design. The intent of the form is to not re-run while entering information, however st.container can do that.

Also, if you want this container ‘form’ to run smoothly and independently of the rest of your streamlit page, I would recommend wrapping in a @st.fragment decorator as so:

import streamlit as st

# Create form using container instead 
@st.fragment
def my_form():
    with st.container(border=True):
        type_of_something = st.selectbox('Type of something', ['type1','type2'])
        
        # precreate columns within container (c_NULL is blank space column, can be removed )
        left,right,c_NULL = st.columns([3, 3, 1])
        if type_of_something == 'type1':
            with left.container(border=True):
                first_provider = st.selectbox('provider1', ['option1','option2'])
                first_model = st.selectbox('model1', ['option1','option2'])
            with right.container(border=True):
                second_provider = st.selectbox('provider2', ['option1','option2'])
                second_model = st.selectbox('Model2', ['option1','option2'])
        else:
            with left.container(border=True):
                first_provider = st.selectbox('provider3', ['option1','option2'])
                first_model = st.selectbox('model3', ['option1','option2'])
            with right.container(border=True):
                second_provider = st.selectbox('provider4', ['option1','option2'])
                second_model = st.selectbox('model4', ['option1','option2'])
        
        submitted = st.button('Submit')

    if submitted:
        # Record form results here 
        pass

my_form()

Let me know if this works for you.