I have an issue in my app that can be reproduced with this code.
import streamlit as st
def do_something():
st.write(st.session_state.text)
def main():
st.set_page_config(layout="wide", page_title='Test for click')
st.button("Button", on_click=do_something)
text_area_container = st.empty()
st.session_state.text = text_area_container.text_area("Write something")
if __name__ == '__main__':
main()
Basically, if you change the value on the text area and then you click on the button you need a second click for the callback to be called. How could I fix this?
In the future, please make sure you code is posted as a code block (using ```), not as a quote block, because otherwise it doesnât work when copy and pasted.
The recommended way to add some widgetâs value to session_state is to assign a key to it. Hereâs some slightly changed code which works fine:
import streamlit as st
def do_something():
st.write(st.session_state.text)
st.button("Button", on_click=do_something)
text_area_container = st.empty()
text_area_container.text_area("Write something", key="text")
It still is having the same issue though. For example, write something on the textarea and click the button. This works fine the first time. Now change what you wrote by writing something else and click the button again, now the text disappears and you need to click again (a second time) for the new text to show up.
Ah, I think I know why thatâs happening â you have two different widgets, a button and a textarea. The button causes the app to rerun if you press it, but the textarea also causes the rerun if you âsubmitâ it. On my computer, I can either cause the textarea to be submitted by hitting command+enter, or by clicking somewhere else on the app. If I try to click on the button, sometimes I accidentally end up just submitting the text box instead. If you intentionally or accidentally make the textarea submit, then it will rerun the app and the buttonâs callback wonât appear anymore.
Can you describe the exact behavior that you would like? Do you simply want the text to appear once if the button is pressed, and to stay there and update any time the text area is re-submitted?
Yes Iâm assuming when I click the button it is interpreting it as a textarea submit maybe? I donât know. I show in the video above the behavior. In my real app Iâm using my text area as a simple text editor where the user can change the text and click on a button to save the edited text to the database. But everytime I change it and want to save it I need to click the button twice.
So in the example above, the intended behavior would be that each time I click on the button the text that is currently on the textarea shows up. That it doesnât disappear on the first click like it does now. It will need to update the text so to speak.
Yes, I think thatâs exactly whatâs happening. So itâs not as much that youâre sending two button clicks, as the first one is being interpreted (by the browser, presumably, not by streamlit) as a âdeselecting the text_areaâ click, rather than a button click. I can successfully click on the button and get the text to be updated nearly every time, but I also see the issue youâre experiencing at times.
Also set the callback of text area to do_something() aside from the button. And set the key to âtextâ. This way, if button is clicked the text in text_area will be shown and if the user sends control+enter or clicking outside of the text_area, text in text_area is also captured. Note the text_area has two ways to trigger update, one is control+enter and two is clicking outside of text_area.
Overall, clicking outside of the text_area is not nice. The users might just resting or thinking, or receiving emergency calls, etc. And so click outside of the text_area and yet it triggers an update which is not their real intention.
Form
So perhaps the best in this situation is to use a form. There are only two triggers, clicking the form button and control+enter in the text_area.
def main():
with st.form('form', clear_on_submit=True):
st.text_area('write something', key='text')
st.form_submit_button('save', on_click=do_something)
Chat
Yet another option is to use the chat_input. There are two triggers, clicking the send button and pressing enter. The users may utilize multi-line by pressing shift+enter keys.
Thanks for the useful help! Both messages helped me fix other issues with my app. For the issue of this thread I found this text editor and it seems to avoid the double click problem and works better for my case as an editor than the text area so I will be switching and see how it goes.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking âAccept allâ, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.