使用 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 和多个依赖/耦合输入

如何在 Shiny 中引用 ui.R 中的反应元素

R Shiny - 我无法从selectInput操作中检索选定的输出值

R Shiny Dynamic选择输入 - 捕获事件