Seeking advice on selectbox element and dynamic UI

Hi all, I am running a local app using Streamlit v1.38.0 and Python 3.11.9

I am trying to build an dynamic UI using Streamlit. The idea is fairly straightforward. I have a database on my PC with all the data. Using Python and Streamlit, I connect to the database and gather all results. Once the results are gathered, I display a selectbox component with a number of dates, once a option is selected, I filter the data and display it as a table.

@st.fragment
def plot_counters(tabledata, header_text):
    st.header(header_text)
    st.table(data = tabledata)
    return None

def main(user, password):
#some logic to poll all available data to generate a filtering list
col1, col2 = st.columns(2)
        with col1:
            selection1 = st.selectbox("Select record from menu:", options=timestamps, key="IMC", index=None)
            IMC_counters = utils.read_counters(selection1) #some function to poll data
            plot_counters(IMC_counters , "Viewing records")
        with col2:
            selection2 = st.selectbox("Select record from menu:", options=timestamps, key="SPC", index=None)
            SPC_counters = utils.read_counters(selection2) #some function to poll data
            plot_counters(SPC_counters , "Viewing records")
return None

if __name__ == '__main__':
    st.set_page_config(layout="wide")
    user = st.text_input("Input Username to use for authorization")
    password = st.text_input("Input Password to use for authorization", type="password")
    if st.button("Submit"):
        main(user,password)

However, when using the following code, the webpage refreshes at each selection. I understand that this is intended behaviour. I have read that st.fragment would allow me to partially run the code but using this still causes the entire page to reload.

Is my approach to displaying the tables incorrect? I tried using on_change parameter to run the displaying function but that causes the same issue.
My vision is that I would have two selectbox, one in each column and whenever I select from the dropdown from one of the selectbox, the respective column is updated with the display table.
Any advice and direction is greatly appreciated. Thanks!

Looks like the answer was rather simple. The fragment itself should be run outside the main code. Here’s how the answer would look like:

@st.fragment
def plot_counters(header_text, timestamps, unqkey):
    selection1 = st.selectbox("Select record from menu:", options=timestamps, key=unqkey, index=None)
    IMC_counters = utils.read_counters(selection1) #some function to poll data
    st.header(header_text)
    st.table(data = IMC_counters )
    return None

def main(user, password):
#some logic to poll all available data to generate a filtering list, 
timestamps  = output_list
col1, col2 = st.columns(2)
        with col1:
            plot_counters("Header text 1", timestamps, "IMC")
        with col2:
            plot_counters("Header text 2", timestamps, "SPC")
return None

if __name__ == '__main__':
    st.set_page_config(layout="wide")
    user = st.text_input("Input Username to use for authorization")
    password = st.text_input("Input Password to use for authorization", type="password")
    if st.button("Submit"):
        main(user,password)
1 Like

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