What causes a Streamlit form to refresh after clicking the submit button and how can I fix it?

I have a streamlit form that takes user input in the st.input_text widget. However, everytime I click submit, the form refreshes and all the input is lost before the submission logic is implemented.

As such, nothing is ever submitted to my google sheet.

with st.form(key="payments"):

    st.markdown(
        "**Hi foo, please choose the month and year for which you are entering data**")

    month, year = st.columns(2)

    with month:
        selected_month = st.selectbox("Month", months)

    with year:
        selected_year = st.selectbox("Year", years)

    status, name_column, amount = st.columns(3)

    
    name_column.markdown("_Name_")
    amount.markdown("_Amount (ugx)_")

    name_input = dict()
    input_amounts = dict()

    for name in names:

        amount_key = str(fx.create_guid())

        name_input[name] = amount_key

        with name_column:
            st.write(name)
            st.write("")
        with amount:
            input_amounts[amount_key] = st.text_input(
                placeholder="ugx", label=" ", label_visibility="collapsed", disabled=False, key=amount_key)

    submitted = st.form_submit_button("Save")
    
    if submitted:
    
       'Open google sheet'
    
        for k, v in name_input.items():
    
            amount_entered = input_amounts[v]
    
            if amount_entered.strip() != "" and int(amount_entered) > 0:
              
                all_values = worksheet.get_all_values()
                next_row_index = len(all_values) + 1
    
               # data to insert
                data = [selected_month, k, amount_entered, selected_year]
    
                print(data)
    
                # insert data in the next row
                worksheet.append_row(
                    data,
                    value_input_option='user_entered',
                    insert_data_option='insert_rows',
                    table_range= #table_range)

However when I put a default value for the st.input_text widgets, the insertion works.

1 Like

I ran your code (after fixing syntax and defining the undefined names) and the form does not refresh when clicking the submit button.

Hi @Goyo, thank you for your response.

What do you think the problem could be then? How come when I click submit, the user input is lost? I have been at this for a few days now.

Additionally, for my own learning, could you please share the syntactically corrected code?

Thank you

@Goyo, were you able to insert the user input in a sheet of your own?

I wonder what Iโ€™m missing

What do you think the problem could be then? How come when I click submit, the user input is lost? I have been at this for a few days now.

I donโ€™t know, but it depends on code that you didnโ€™t post here,

Additionally, for my own learning, could you please share the syntactically corrected code?

You just need to fix the indentation in line 41 and use a valid python expression instead of #table_range in line 61.

were you able to insert the user input in a sheet of your own?

Yes, but I donโ€™t see how that could be related to the issue of the form refreshing. The contents of the form donโ€™t depend on what is in the worksheet.

Hello, I figured out the problem. It was never the form refreshing as @Goyo mentioned.

There is no need to store the values of the different input boxes using the input_amounts dictionary. It gets loaded with blank values when the form loads which never get updated after the user clicks submit.

Instead, I just leveraged the keys of the input boxes and used session state to retrieve the values entered. This is shown in the corrected code below;

with st.form(key="payments"):

    st.markdown("**Hi foo, please choose the month and year for which you are entering data**")

    month, year = st.columns(2)

    with month:
        selected_month = st.selectbox("Month", months)

    with year:
        selected_year = st.selectbox("Year", years)

    st.write("---")

    st.markdown("**Member payments**")

    name_column, amount = st.columns(2)

    name_column.markdown("_Name_")
    amount.markdown("_Amount (ugx)_")

    name_input = dict()
    
    counter = 1

    for name in names:

        amount_key = f"key{counter}"

        name_input[name] = amount_key

        with name_column:
            st.write(name)
            st.write("")
        with amount:
                st.text_input(
                placeholder="ugx", 
                label=" ", 
                label_visibility="collapsed", 
                disabled=False, 
                key=amount_key)
                
        counter += 1
    
    submitted = st.form_submit_button("Save")
    
    if submitted:
        
        payments_for_insertion=[]
       
        for name, amount_key in name_input.items():
            
            amount_entered = st.session_state.get(amount_key,"")
    
            if amount_entered.strip() != "" and int(amount_entered) > 0:
                
                data = [selected_month, name, amount_entered, selected_year]
    
                payments_for_insertion.append(data)

        if payments_for_insertion:
                
            'Open Worksheet'

            all_values = worksheet.get_all_values()
        
            next_row_index = len(all_values) + 1

            worksheet.append_rows(
                    payments_for_insertion,
                    value_input_option='user_entered',
                    insert_data_option='insert_rows',
                    table_range='your table_range'"
                )

Thank you @Goyo for pointing me away from the wrong problem !!!

However, how do we clear forms after submission? I get the "clear_on_submit attribute does not exist " error when I try to use it.

You get thar error when you do what?

Sorry, my mistake. I was putting the โ€œclear_on_submitโ€ as a parameter of the submit button instead of the form itself. Thank you.

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