使用 Shiny `renderUI` 时无法运行 JavaScript 代码
Posted
技术标签:
【中文标题】使用 Shiny `renderUI` 时无法运行 JavaScript 代码【英文标题】:Cannot run JavaScript code when Shiny `renderUI` is used 【发布时间】:2021-09-29 14:34:05 【问题描述】:我正在尝试将 JS 脚本(“全选”框)应用到动态呈现的 UI,但以下操作不起作用:
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
uiOutput("checkbox_ui")
)
server <- function(input, output, session)
output$checkbox_ui <- renderUI(
checkboxGroupInput(inputId = "myCheckbox",
label = NULL,
choices = c("All", "A", "B"))
)
runjs(html("
$(\"#myCheckbox input[value='All']\").click(function(e)
$(\"#myCheckbox input[type='checkbox']\").prop('checked', $(e.target).prop(\"checked\"));
);
"))
shinyApp(ui, server)
但是,当我跳过使用renderUI
时,会运行 JS 脚本:
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
checkboxGroupInput(inputId = "myCheckbox",
label = NULL,
choices = c("All", "A", "B"))
)
server <- function(input, output, session)
runjs(HTML("
$(\"#myCheckbox input[value='All']\").click(function(e)
$(\"#myCheckbox input[type='checkbox']\").prop('checked', $(e.target).prop(\"checked\"));
);
"))
shinyApp(ui, server)
有人知道解决方法吗?
【问题讨论】:
【参考方案1】:这是因为在执行runjs
时该复选框尚未呈现。
我会尝试:
runjs(HTML("setTimeout(function()
$(\"#myCheckbox input[value='All']\").click(function(e)
$(\"#myCheckbox input[type='checkbox']\").prop('checked', $(e.target).prop(\"checked\"));
);
);"))
如果这不起作用,我会尝试
observeEvent(input[["myCheckbox"]],
runjs(HTML("
$(\"#myCheckbox input[value='All']\").click(function(e)
$(\"#myCheckbox input[type='checkbox']\").prop('checked', $(e.target).prop(\"checked\"));
);
"))
)
编辑
这是一个可行的解决方案,不使用shinyjs
:
library(shiny)
js <- paste(
"$(document).ready(function()",
" $('body').on('click', \"#myCheckbox input[value='All']\", function(e) ",
" var isChecked = $(e.target).prop('checked');",
" $(\"#myCheckbox input[value!='All']\").prop('checked', isChecked);",
" );",
");",
sep = "\n"
)
ui <- fluidPage(
tags$head(tags$script(HTML(js))),
uiOutput("checkbox_ui")
)
server <- function(input, output, session)
output$checkbox_ui <- renderUI(
checkboxGroupInput(inputId = "myCheckbox",
label = NULL,
choices = c("All", "A", "B"))
)
shinyApp(ui, server)
【讨论】:
感谢您的帮助!第一个 JS 代码没有任何作用,而第二个只有在All
框之前检查过一次之后才起作用。
有没有办法在 UI 中创建一个空的/不可见的checkboxGroupInput
,然后在使用updateCheckboxGroupInput
在服务器函数中创建它之后直接更新它?
你可以试试,听起来很合理。也许只有choices = "All"
的初始checkboxGroupInput
?
@6PO0222 查看我的编辑。一个更简单的工作解决方案。【参考方案2】:
以下工作正常。
js <- "
$(\"#myCheckbox input[value='All']\").click(function(e)
$(\"#myCheckbox input[type='checkbox']\").prop('checked', $(e.target).prop(\"checked\"));
);
"
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
checkboxGroupInput(inputId = "myCheckbox",
label = NULL,
choices = c("All", "A", "B"))
)
server <- function(input, output, session)
observeEvent(input[["myCheckbox"]],
updateCheckboxGroupInput(session,"myCheckbox")
runjs(HTML(js))
, ignoreNULL = FALSE)
shinyApp(ui, server)
renderUI
ui <- fluidPage(
useShinyjs(),
uiOutput("uic")
)
server <- function(input, output, session)
output$uic <- renderUI(
checkboxGroupInput(inputId = "myCheckbox",
label = NULL,
choices = c("All", "A", "B"))
)
observeEvent(input[["myCheckbox"]],
updateCheckboxGroupInput(session,"myCheckbox")
runjs(HTML(js))
, ignoreNULL = FALSE)
shinyApp(ui, server)
【讨论】:
以上是关于使用 Shiny `renderUI` 时无法运行 JavaScript 代码的主要内容,如果未能解决你的问题,请参考以下文章
如何在R Shiny中使用renderUI触发renderDataTable进行输入?
如何使用 `renderUI` 响应式更新 Shiny 应用程序中的活动菜单项?
Shiny Reactive renderUI 和多个依赖/耦合输入