Shiny中passwordInput引发selectInput异常问题求助
Shiny中passwordInput与selectInput的冲突问题及解决办法
问题描述
在Shiny应用中同时使用passwordInput和selectInput组件时,出现以下异常:
- 加载应用时,
selectInput的选中项会莫名多出一个字符; - 使用浏览器保存的密码登录或刷新页面时,
selectInput的下拉菜单会自动展开; - 大型Shiny应用中,部分
selectInput组件也会出现下拉菜单自动展开的情况。
复现代码
shinyApp( ui = fluidPage( selectInput(inputId = "mySelectInput", label = "My Select Input", choices = letters), passwordInput(inputId = "myPasswordInput", label = "Password") ), server = function(input, output, session) {} )
运行环境详情
- Chrome版本:106.0.5249.119(官方版本,64位)
- R版本:4.1.3(2022-03-10)
- 平台:x86_64-pc-linux-gnu(64位)
- 运行系统:Ubuntu 20.04.4 LTS
- 矩阵运算库:默认
- BLAS:/usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
- LAPACK:/usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
- 区域设置:
[1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 LC_COLLATE=C.UTF-8
[5] LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 LC_PAPER=C.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C - 已加载基础包:stats、graphics、grDevices、utils、datasets、methods、base
- 已附加包:shiny_1.7.3
- 通过命名空间加载(未附加):Rcpp_1.0.9、withr_2.5.0、digest_0.6.30、later_1.3.0、mime_0.12、R6_2.5.1、jsonlite_1.8.2、lifecycle_1.0.3、xtable_1.8-4、magrittr_2.0.3、cachem_1.0.6、rlang_1.0.6、cli_3.4.1、rstudioapi_0.14、promises_1.2.0.1、jquerylib_0.1.4、bslib_0.4.0、ellipsis_0.3.2、tools_4.1.3、httpuv_1.6.6、fastmap_1.1.0、compiler_4.1.3、memoise_2.0.1、htmltools_0.5.3、sass_0.4.2
可行解决办法
1. 调整组件渲染顺序
将passwordInput放在selectInput之前,避免浏览器自动填充逻辑优先干扰先渲染的selectInput组件,修改后的UI代码:
ui = fluidPage( passwordInput(inputId = "myPasswordInput", label = "Password"), selectInput(inputId = "mySelectInput", label = "My Select Input", choices = letters) )
2. 禁用密码框自动填充
给passwordInput添加autocomplete="new-password"属性,阻止浏览器自动填充密码的行为,从根源上减少干扰:
passwordInput(inputId = "myPasswordInput", label = "Password", autocomplete = "new-password")
3. 用JavaScript强制重置selectInput状态
在UI中插入自定义JS代码,页面加载完成后强制收起所有selectInput的下拉菜单,同时修正选中项的异常:
ui = fluidPage( selectInput(inputId = "mySelectInput", label = "My Select Input", choices = letters), passwordInput(inputId = "myPasswordInput", label = "Password"), tags$script(HTML(" $(document).ready(function() { // 收起下拉菜单 $('.selectize-dropdown').hide(); $('.selectize-input').removeClass('dropdown-active'); // 修正选中项多余字符问题:重置选中值为第一个选项 let selectize = $('#mySelectInput')[0].selectize; if (selectize) { selectize.setValue(selectize.options[Object.keys(selectize.options)[0]].value); } }); ")) )
4. 替换为第三方select组件
使用shinyWidgets包中的pickerInput替代原生selectInput,第三方组件的渲染逻辑更独立,不易受浏览器自动填充影响:
library(shinyWidgets) shinyApp( ui = fluidPage( pickerInput(inputId = "mySelectInput", label = "My Select Input", choices = letters), passwordInput(inputId = "myPasswordInput", label = "Password") ), server = function(input, output, session) {} )
内容的提问来源于stack exchange,提问作者Ben Ernest
相关产品推荐
相关产品推荐

