I am building a simple chat bot using streamlit. A small problem is that I am collecting user input using text_input. Sometimes, the user clicks away to do something else mid-sentence, and this triggers the “on_change” event, which in my case sends the message to the chat bot and gets a response. The alternative of using a submit button for each sentence in a chat bot seems too tedious, so I am wondering if there are any good workarounds (e.g. a way to track enter keypress, or another method) to the fact that text_input triggers their callback on loss of focus.
Steps to reproduce
input=st.text_input("Type your response here")
st.write(f"User input is:{input}")
If writing in this textbox and click away, their input will still be written below.
Thanks, I’m totally new to javascript and writing components, but I took what you wrote as inspiration and looked up how to apply this to text_inputs as well. Here is a version that I can apply to all text_inputs, or even a single text_input so that enter works, but not focusout. Super helpful thank you!
import streamlit as st
import streamlit.components.v1 as components
toggle_all=st.checkbox("""Turn on "focus out" component for all text inputs""")
toggle_first=st.checkbox("""Turn on "focus out" component for text input 1 only.""")
x=st.text_input("1 Type something here")
y=st.text_input("2 Type something here as well")
st.write(f"Result of input box 1: {x}")
st.write(f"Result of input box 2: {y}")
if toggle_all:
#This looks for any input box and applies the code to it to stop default behavior when focus is lost
components.html(
"""
<script>
const doc = window.parent.document;
const inputs = doc.querySelectorAll('input');
inputs.forEach(input => {
input.addEventListener('focusout', function(event) {
event.stopPropagation();
event.preventDefault();
console.log("lost focus")
});
});
</script>""",
height=0,
width=0,
)
if toggle_first:
#This will apply only to an input with a specific label (aria-label)
components.html(
"""
<script>
const doc = window.parent.document;
const input = doc.querySelector('input[aria-label="1 Type something here"]');
input.addEventListener('focusout', function() {
event.stopPropagation();
event.preventDefault();
console.log('Lost focus');
});
</script>
""",
height=0,
width=0,
)
```