【问题标题】:R Shiny - Using a custom message handler to disable a single radio button in a radio button groupR Shiny - 使用自定义消息处理程序禁用单选按钮组中的单个单选按钮
【发布时间】:2019-08-21 02:50:42
【问题描述】:

下面的应用程序包含一个带有两个选项(downloadupload)的 selectInput input$set1 和一个使用 renderUI() 呈现的单选按钮组 input$set2。我正在使用自定义消息处理程序,它根据 selectInput 的值禁用单选按钮组中的单选按钮(如果 input$set1 == 'download' 则禁用 upload 单选按钮,否则启用它)。

这是应用程序:

library(shiny)
library(shinyWidgets)
library(shinydashboard)

toggleRadioOpt <- function(session, inputId, choice, enable = TRUE, selected) {
  session$sendCustomMessage(
    type = 'toggleRadioOpt',
    message = list(id = inputId, choice = choice, enable = enable, selected = selected)
  )
}

modUI <- function(id) {

  ns <- NS(id)

  tagList(

    tags$head(
      tags$script("

                  Shiny.addCustomMessageHandler('toggleRadioOpt',
                  function(data) {
                  $('#' + data.id + ' input[value = \"' + data.choice + '\"]').attr('disabled', !data.enable).prop('checked', false);
    if(data.selected !== null) {
                  $('#' + data.id + ' input[value = \"' + data.selected + '\"]').prop('checked', true);
}
                  }
                  );

                  ")
      ),

    prettyRadioButtons(ns('set1'), label = 'Select', choices = c('download', 'upload', 'abb')),

    # selectInput(ns('set1'), label = 'Select', choices = c('download', 'upload', 'sql')),

    uiOutput(ns('taskUI'))

      )

}


modServer <- shinyServer(function(input, output, session) {
  ns = session$ns

  output$taskUI <- renderUI({

    switch(input$set1, 
           'download' = selectInput(ns('data'), '', state.area),
           'upload' = selectInput(ns('data'), '', state.center),
           'abb' = tagList(
             selectInput(ns('data'), '', state.abb), 
             actionButton(ns('upload'), 'Upload')
             )
           )

    prettyRadioButtons(ns('set2'), label = '', choices = c('split', 'upload'))

  })

  observe({

    if(!is.null(input$set2)) {

      if(input$set1 %in% c('download', 'abb')) {

        toggleRadioOpt(session = session, inputId = ns('set2'), choice = 'upload', enable = F, selected = 'split')

      } else {

        toggleRadioOpt(session = session, inputId = ns('set2'), choice = 'upload', enable = T, selected = 'split')

      }

    }

  })
})


# UI ----------------------------------------------------------------------
ui = fluidPage(modUI('first'))

# SERVER ------------------------------------------------------------------
server <- shinyServer(function(input, output, session) {

  callModule(modServer, 'first')  

})

shinyApp(ui, server)

如果在 UI 中创建单选按钮组,则处理程序按预期工作,但如果使用 renderUI() 创建按钮则失败。具体来说,它在启动时失败,但如果随后更改 input$set1 则可以工作。我是使用自定义消息处理程序的新手,所以我不确定这里发生了什么或如何修复它。我认为这可能与加载 UI 之前触发的 jQuery 有关,但我不能确定。

【问题讨论】:

    标签: javascript jquery html r shiny


    【解决方案1】:

    我认为这可能与触发的 jQuery 有关 在 UI 加载之前,但我不能确定。

    我想是的。在 UI 加载之前,input$set2NULL。你可以这样做:

      observe({
        if(!is.null(input$set2)){
          if(input$set1 == 'download') {
            toggleRadioOpt(session = session, inputId = ns('set2'), choice = 'upload',
                           enable = F, selected = 'split')
          } else {
            toggleRadioOpt(session = session, inputId = ns('set2'), choice = 'upload', 
                           enable = T, selected = 'split')
          }
        }
      })
    

    【讨论】:

    • 如果我只在renderUI 内渲染set2,但如果多个元素以set1 的值为条件渲染则不行。我已经编辑了我的帖子以显示一个例子,请问可以看看吗?将其他元素添加到 if 语句中不起作用。我采用任意延迟将toggleRadioOpt(...) 放入shinyjs::delay()。这可行,但我不确定这是否是最好的方法。
    猜你喜欢
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多