How do you clear the input box after hitting enter?

Summary

I am creating a todo web app, and while testing it I notice when I hit enter when there was text in the input box the text remained there!

Steps to reproduce

Code snippet:

import streamlit as st

import function

todos = function.get_todos()


def add_todo():
    todo = st.session_state["new_todo"] + '\n'
    todos.append(todo)
    function.write_todos(todos)


st.title("My Todo App")
st.subheader('This is my todo app.')
st.write("The app is to increase your productivity")

for index, todo in enumerate(todos):
    checkbox = st.checkbox(todo, key=todo)
    if checkbox:
        todos.pop(index)
        function.write_todos(todos)
        del st.session_state[todo]
        st.experimental_rerun()
st.text_input(label=' ', placeholder='Add new todo...',
              on_change=add_todo, key='new_todo')


* Link to your deployed app: https://nishanth-pallela-my-todo-app-todowebapp-7h260z.streamlit.app/
Visit the link above to get to my app.
Please help me!!

Hey @Nishanth-Pallela,

Check out @mathcatsand’s awesome answer for this question here.

def add_todo():
todo = st.session_state[“new_todo”] + ‘\n’
todos.append(todo)
function.write_todos(todos)

# Clear the input box after hitting enter
st.session_state["new_todo"] = ""

##This code works by first storing the value of the input box in the session state. Then, after the user hits enter, the session state is cleared. This will cause the input box to be empty the next time the user clicks on it.

1 Like

Thx so much!

2 Likes

A slight change to @mathcatsand’s solution where using the get() method, there’s no need to initialize a key in the session state beforehand. Also, see this post on Stack Overflow.

A working solution:

import streamlit as st

def clear_text():
    st.session_state.my_text = st.session_state.widget
    st.session_state.widget = ""

st.text_input('Enter text here:', key='widget', on_change=clear_text)
my_text = st.session_state.get('my_text', '')
#                          ^^^   <--- here
st.write(my_text)

It’s so very simpler than the most people’s approach, we didn’t even need a seperate function for it! But anyway i have solved it myself, and in my case i have to store the value in database so i had to use custom function which i use to store the text in the text_inbox so i added this single line to my write_text function and that’s it, simple as that. I don’t understand why are people usually trying to make it look harder than it is. I am not saying that it’s (coding) easy or anything but it’s not impossible difficult either, it can be achieved.

I played around with this for a while and found these solutions finicky. They didn’t do exactly what I wanted and required me to do a bunch of “stuff” to manage state. The beautiful thing about streamlit is that you don’t need to know about those types of things. Managing a bunch of text boxes as described above feels very off-brand for the awesomeness of streamlit.

I use the nav_to function that was shown here a while back. When I decide the page needs to be “reset,” I redirect to the current page. That way, I don’t need to do ANY state management; I just got the page reloaded, which seems quite happy to give me a new clean form. The only pain point for this code is knowing if you are on the dev server or the production server since the URLs for these are different. In my actual nav_to function I have a way to make URLs know if they should be production or development.

def nav_to(url):
    """
    Redirects the user to a new web page by generating a meta refresh tag.
    This was recommended here:
    https://discuss.streamlit.io/t/programmatically-send-user-to-a-web-page-with-no-click/21904/6

    Parameters:
        url (str): The URL of the destination web page.

    Example:
        nav_to('https://example.com')  # Redirects to https://example.com
    """
    nav_script = f"""<meta http-equiv="refresh" content="0; url='{url}'">"""
    st.write(nav_script, unsafe_allow_html=True)

Then I write code that looks like this:

    if pressed:
        ST_Data.log_job_comment(note):
        st.success('Comment Saved')
     
        # Allow the user to see the status
        time.sleep(1.0) 

        # Now jump to the same page to force a refresh
        st_tool.nav_to("http://localhost:8501/PCSJobComment")

The simplest way to me would be modifying the following function: ^^ last line

def add_todo():
    todo = st.session_state["new_todo"] + "\n"
    todos.append(todo)
    functions.write_todos(todos)
    st.session_state["new_todo"] = ""