#Solution : How to Reset a Streamlit Form When "Clear on Submit" Isn't an option

Sometimes, resetting a form in Streamlit can feel more challenging than it should be. The default option, clear_on_submit=True, doesn’t always work for every scenario. Here are some common challenges:

  • Complex forms with reruns: If your form uses dialog boxes or other elements that trigger a rerun of the app, you unintentionally lose input values.
  • Not using st.form_submit_button: If your form doesn’t use st.form_submit_button, the clear_on_submit feature won’t work at all.
  • Using st.form_submit_button with additional logic: If you perform extra processing, such as input validation or saving data to a database, the form may reset before you’re done with the data.

What seems like a simple task can quickly become frustrating. I explored many posts on the Streamlit Community forum, but none of the solutions worked for my use case.

My Approach: Simple, Scalable, and Effective

The solution is to break the form into two parts. By separating the form logic, you can control when the form is displayed and reset it as needed. This approach allows you to “re-render” the form on demand, effectively resetting it without losing control over your application flow.

Here’s the approach I used, simplified into an example scenario.

The Idea

Instead of relying on clear_on_submit, you can:

  1. Track Your Form State with st.session_state:
    Use st.session_state to store essential variables that dictate which form or step the user is on.

  2. Control What’s Displayed Based on State:
    For example, you might:

    • Show a “Setup” form if st.session_state["form_loaded"] is not set.
    • Show your main form if st.session_state["form_loaded"] is True.
  3. Resetting the Form by Clearing Session Keys:
    When the user wants to reset, just remove the session keys and call st.rerun().

A Quick Example

Initial State:

if "form_loaded" not in st.session_state:
    st.session_state["form_loaded"] = False

#Loading the Form:
if not st.session_state["form_loaded"]:
    if st.button("Load Form"):
        st.session_state["form_loaded"] = True
        st.rerun()
else:
    st.write("Here's your form!")
    # ... form fields and submit button ...

#Resetting the Form:
if st.button("Back"):
    # Remove the key that shows the form
    del st.session_state["form_loaded"]
    st.rerun()

In this example:

  • Before loading, form_loaded is False, so the user sees a “Load Form” button or a landing view.
  • After clicking “Load Form”, form_loaded becomes True and the main form appears.
  • If they hit “Back,” we delete form_loaded and rerun, returning to the initial screen.

Why This Works

  • By using session_state, you treat certain keys as “flags” that determine what part of your app is shown.
  • Removing these keys resets the state back to an earlier form of your app.
  • Here’s a bug with Streamlit form - Even if you remove all the Session state variables, the form values entered by user a still visible even after the st.rerun. And hence, by having an initial landing form/view - we force Streamlit to re-render the form.
  • st.rerun() immediately re-executes the script, making the UI reflect the cleared state.

Key Takeaways

  • Break form into two parts !
  • Use st.session_state to control your app’s flow.
  • Delete session keys to revert to a previous state, effectively “resetting” your form.
  • Combine these tricks with st.rerun() to refresh the UI instantly.

This method is flexible and can be adapted to multiple-step forms, complex states, or any time you need to reset user input back to a known starting point.

Happy to receive input and suggestions from the community !

PS - Thanks for the Streamlit team for this amazing tool.