Disable textInput based on radio button selection

2020-07-10 09:47发布

Say I have the following Shiny App:

library(shiny)
ui <- fluidPage(
  column(3,
         radioButtons("radios", "",
                      c("Enabled" = "enabled",
                        "Disabled" = "disabled"),
                      inline = TRUE)
  ),
  column(4, textInput("text", "", value = "Disable me"))
)
server <- function(input, output) {

}
shinyApp(ui=ui, server=server)

What's the easiest way to disable the textInput based on the selected radio button? I know I just have to add ... disabled /> to the input tag, but I have no idea on how to do that in Shiny.

I tried building the full tag "manually" by pasting the HTML as a string, the selected radio value and the rest of the HTML, using uiOutput and renderUI (based on this), but that didn't work.

The textInputgenerates this:

<input id="text" type="text" class="form-control" value="Disable me"/>

and I need to be able to switch between the above and this:

<input id="text" type="text" class="form-control" value="Disable me" disabled />

标签: r shiny
2条回答
Explosion°爆炸
2楼-- · 2020-07-10 10:13

You could do this with session$sendCustomMessage on the server (which generates javascript that disables or enables the text box) and Shiny.addCustomMessageHandler in the UI (which executes the javascript).

library(shiny)
ui <- fluidPage(
  tags$head(tags$script(HTML('
      Shiny.addCustomMessageHandler("jsCode",
        function(message) {
          eval(message.code);
        }
      );
    '))),
  column(3,
         radioButtons("radios", "",
                      c("Enabled" = "enabled",
                        "Disabled" = "disabled"),
                      inline = TRUE)
  ),
  column(4, textInput("text", "", value = "Disable me"))
)
server <- function(input, output, session) {
  observe({
    if(input$radios == "disabled") {
      session$sendCustomMessage(type="jsCode",
                                list(code= "$('#text').prop('disabled',true)"))
    } else {
      session$sendCustomMessage(type="jsCode",
                                list(code= "$('#text').prop('disabled',false)"))
    }
  })
}
shinyApp(ui=ui, server=server)
查看更多
欢心
3楼-- · 2020-07-10 10:31

This kind of stuff is actually very trivial if you use the shinyjs package - it was built exactly because these questions popped up so often. There are are functions called disable and enable that you can call in your server to disable/enable an input, or you can use the toggleState function to enable/disable based on a condition. Here is how to achieve what you want with minimal code without having to use JavaScript:

library(shiny)
ui <- fluidPage(
  shinyjs::useShinyjs(),
  column(3,
         radioButtons("radios", "",
                      c("Enabled" = "enabled",
                        "Disabled" = "disabled"),
                      inline = TRUE)
  ),
  column(4, textInput("text", "", value = "Disable me"))
)
server <- function(input, output, session) {
  observe({
    shinyjs::toggleState("text", input$radios == "enabled")
  })
}
shinyApp(ui=ui, server=server)

All I had to do to modify your original code was to add a call to shinyjs::useShinyjs(), add the session parameter to the server, and add the call to shinyjs::toggleState().

Disclaimer: I wrote the shinyjs package

查看更多
登录 后发表回答