Why does my text input not focus with script in component.html when sessionstore is unchanged?

Hello,

I came across this topic when I was trying to find a way to .focus() a text input when the script is rerun

The approach shown there works fine, but I would like to know why it only
works when st.session_state['counter'] changes. It the line where it is incremented is commented the text box will not focus. If the counter increases, the text box
is focused when the button is clicked, the text input is sent via Enter or the select box changes (every time the callback is triggered).

This is the code:

import streamlit.components.v1 as components
import streamlit as st

def cbk():
    st.session_state['delete_line'] = True
    # st.session_state['counter'] += 1

option = st.selectbox('', [1,2,3], 
                              index=1,
                              key='id_combo',
                              on_change=cbk)

if 'delete_line' not in st.session_state:
    st.session_state['delete_line'] = True

if 'counter' not in st.session_state:
    st.session_state['counter'] = 0


if st.session_state['delete_line']:

    st.session_state['id_answer'] = ''
    st.session_state['delete_line'] = False

y = st.text_input(f'', key='id_answer', on_change=cbk)    

components.html(
    f"""
        <div>some hidden container</div>
        <p>{st.session_state.counter}</p>
        <script>
            var input = window.parent.document.querySelectorAll("input[type=text]");

            for (var i = 0; i < input.length; ++i) {{
                input[i].focus();
            }}
    </script>
    """,
    height=150
)

st.write(f'the submitted answer was {y}')

if st.button('Check', on_click=cbk):
    st.session_state['delete_line'] = True
2 Likes

Hello @solarjoe,

When your script reruns, Streamlit does not re-render HTML components that donโ€™t change. And if they donโ€™t change, javascript code included in them wonโ€™t be executed again.

So, to force Streamlit to re-render the component and execute its javascript code multiple times, we need to apply some change to it, hence the st.session_state.counter.

Hello @okld,
thanks for the quick reply and the explanation!

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