Issues with nested button + selectbox

Hello Community,
I am trying to create a nested structure of buttons and selectbox.

list_city_from_db
city=st.selectbox(" Select a city",list_city_from_db)
b1=st.button("See further options")
if b1:
       suburbs=st.selectbox("Select Suburb",sub)
       if suburbs:
                       col1,col2 = st.columns(2)
                       with col1:
                                      select_bus=st.selectbox("Available Bus",bus_schedule)
                                      bus_timetable=st.download_button("Download Bus timetable",data=df.to_csv(),....)

                        with col1:
                                      select_train=st.selectbox("Available Train",Train_schedule)
                                      train_timetable=st.download_button("Download train timetable",data=df.to_csv(),....)

The issue that I am facing is when I select the suburb after entering the city, it disappears.
What should I do to avoid this issue? Is the session state the solution? for answers to questions.

I don’t know if it’s the only solution, but yes, session state would be an easy fix for this.

Just define a function that changes the session state variable to 0 if it is 1, or 1 if it is 0. Call the function whenever the button is clicked with the on_click option in st.button.

Then show the suburb if the variable = 1.

Thanks for your reply. I have only one question.

Let’s take an example.

A User first enters a city and hits the button. Then our session state will be 1. We will be showing the suburbs since state=1. Then user changes the city and hits the button . Now, session state will be 0. and we will not show suburb.

How to get around this?

Not sure I understand your code structure.

b1=st.button("Enter your city")

This is a button, how can the user enter a city?

Sorry for the ambiguity.

I have a list of cities that is displayed in a selectbox.
Once the user has selected the city, we want the user to hit the button so we will show the user another selectbox that will have a list of suburbs.
After selecting the suburb we will show Available bus and train timetable as showed in sample code.

Note: I’ll update the code supplied.

Ah ok, makes sense!
FYI, an st.form is pretty much ideal for this purpose.

I just have something to do, then will come back and put together an example

thanks. I will checkout st.form.

Update: I checked st.form and we cannot have st.download_button in a form. :frowning:

Hi @Ninad_Pethkar, try the following:

  1. delete the following lines:
b1=st.button("See further options")
if b1:
  1. accordingly, reverse indent the remaining code lines from the deletion point onwards

Cheers

I’m not sure if the following code will serve your purpose:

import streamlit as st

# init session value
if 'btn' not in st.session_state:
    st.session_state['btn'] = False


def callback1():
    st.session_state['btn'] = True


def callback2():
    st.session_state['btn'] = False


city = st.selectbox(" Select a city", ['a', 'b'], on_change=callback2)
b1 = st.button("See further options", on_click=callback1)
if st.session_state['btn']:  # session value judge
    suburbs = st.selectbox("Select Suburb", "sub")
    if suburbs:
        col1, col2 = st.columns(2)
        with col1:
            select_bus = st.selectbox("Available Bus", "bus_schedule")
            bus_timetable = st.download_button("Download Bus timetable", data="df.to_csv()", )

        with col1:
            select_train = st.selectbox("Available Train", "Train_schedule")
            train_timetable = st.download_button("Download train timetable", data="df.to_csv()", )

1 Like

Looks like you have some other replies above, but this seems to work for me

import streamlit as st

if 'my_city' not in st.session_state:
    st.session_state['my_city'] = None

list_city_from_db = ['city_a','city_b','city_c']
sub = {'city_a'    :    ['sub_1','sub_2'],
       'city_b'    :    ['sub_3','sub_4'],
       'city_c'    :    ['sub_5','sub_6']}
bus_schedule = ['bus_a','bus_b']


with st.form('my_form'):
    city=st.selectbox(" Select a city",['please select one'] + list_city_from_db)
    st.write(city)
    
    submitted = st.form_submit_button("Submit")
    if submitted:
        st.session_state['my_city'] = city
        
        
if st.session_state['my_city'] is not None:
    suburbs=st.selectbox("Select Suburb",['please choose one'] + sub[st.session_state['my_city']])
    
    if suburbs != 'please choose one':
        mybus=st.selectbox("Select bus",['please choose one'] + bus_schedule)
        
        if mybus != 'please choose one':
            st.write(mybus)
        
    
    
        

Thank you. This works!

This would work if we did not want to include download button. Unfortunately, I want to include a download button. But thanks for your time and comments.

Sorry, I don’t understand.
You can add a download button outside of the form!

Only this bit is the form

with st.form('my_form'):
    city=st.selectbox(" Select a city",['please select one'] + list_city_from_db)
    st.write(city)
    
    submitted = st.form_submit_button("Submit")
    if submitted:
        st.session_state['my_city'] = city

You will add your download button here

if st.session_state['my_city'] is not None:
    suburbs=st.selectbox("Select Suburb",['please choose one'] + sub[st.session_state['my_city']])
    
    if suburbs != 'please choose one':
        mybus=st.selectbox("Select bus",['please choose one'] + bus_schedule)
        
        if mybus != 'please choose one':
            st.write(mybus)

That second part is not in a form

ok. Understood! Thanks.

1 Like