streamlit的text input组件获取焦点

文章目录


前言

近期一个项目中,使用streamlit作为用户交互的UI,要求能够使用扫码枪输入编码,使用了text input组件,但运行时发现默认的焦点并不在text input上,需要鼠标点击一下才行,操作不友好,找了不少资料后,终于解决,做下记录。


首先通过搜索工具,查到最接近的帖子如下

https://discuss.streamlit.io/t/why-does-my-text-input-not-focus-with-script-in-component-html-when-sessionstore-is-unchanged/18289

使用如下代码

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

其中关键的是JavaScript的这段

input = window.parent.document.querySelectorAll("input[type=text]");
input[i].focus();

也就是获取所有的输入组件,并将焦点固定到最后一个输入框。

写了个测试代码进行调试,该方法可行

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


st.text_input(label='电池编号:')
st.text_input('电池型号:')

components.html(
        f"""
            <script>      
                var allinputs = window.parent.document.querySelectorAll("input[type=text]");
                allinputs[0].focus();
            </script>
        """
    )

即获取所有的输入组件,并将焦点放到第1个组件,但这样ui修改后,需要知道需要获取的焦点组件顺序才行,最好是能够通过组件的编号信息来设置。

对运行的网页进行查看,发现其有个 aria-label的属性,该属性就是我们在streamlit里设置的label值

在这里插入图片描述
故按如下修改JS的代码,便可通过label来设置焦点

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


st.text_input(label='电池编号:')
st.text_input(label='电池型号:')

components.html(
        f"""
            <script>      
                var batsn = window.parent.document.querySelector('[aria-label="电池编号:"]');
                batsn.focus();
            </script>
        """
    )
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值