最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - How to Disable a Button in a Shiny Nested Module? - Stack Overflow

programmeradmin0浏览0评论

I am trying to disable an action button inside a Shiny module when a specific radio button value is selected. Specifically, when "Log-normal" ("lnorm") is selected from the radioButtons, the "Go!" button should be disabled. Otherwise, the button should remain enabled.

The main constraint is that the disable / enable button must remain inside module 2, so I cannot move it to module 1

I am using shiny modules and shinyjs for enabling/disabling the button. However, my current implementation does not disable the button as expected. Here is my implementation:

library(shiny)
library(shinyjs)

mod_1_ui <- function(id) {
  ns <- NS(id)
  
  fluidRow(
    column(
      width = 3,
      radioButtons(
        ns("dist"),
        "Distribution type:",
        c(
          "Normal" = "norm",
          "Uniform" = "unif",
          "Log-normal" = "lnorm",
          "Exponential" = "exp"
        )
      ),
      actionButton(
        inputId = ns("btn_go"),
        label = "Go !",
        icon = icon("play")
      )
    ),
    column(
      width = 9,
      mod_2_ui(ns("display_plot"))
    )
  )
}

mod_1_server <- function(id, r_global) {
  moduleServer(id, function(input, output, session) {
    show <- reactive({
      input$btn_go
    })
    
    mod_2_server("display_plot", show = show, btn_go_id = session$ns("btn_go"), dist = reactive({ input$dist }))
  })
}

mod_2_ui <- function(id) {
  ns <- NS(id)
  
  plotOutput(outputId = ns("plot"))
}

mod_2_server <- function(id, show, btn_go_id, dist) {
  moduleServer(id, function(input, output, session) {
    
    observeEvent(dist(), {
      print(dist())  # Debugging output to check reactive value
      if (dist() == "lnorm") {
        shinyjs::disable(id = session$ns("btn_go"))  # Trying to disable the button
      } else {
        shinyjs::enable(id = session$ns("btn_go"))
      }
    })
    
    observeEvent(show(), {
      output$plot <- renderPlot({
        plot(runif(10, runif(10)))
      })
    })
    
  })
}

ui <- fluidPage(
  useShinyjs(),  # Required for shinyjs to work
  mod_1_ui("mod")
)

server <- function(input, output, session) {
  r_global <- reactiveValues()
  
  mod_1_server("mod", r_global = r_global)
}

if (interactive()) {
  shinyApp(ui, server)
}

How can I properly disable the "Go!" button when "Log-normal" is selected in this modularized Shiny app?

I am trying to disable an action button inside a Shiny module when a specific radio button value is selected. Specifically, when "Log-normal" ("lnorm") is selected from the radioButtons, the "Go!" button should be disabled. Otherwise, the button should remain enabled.

The main constraint is that the disable / enable button must remain inside module 2, so I cannot move it to module 1

I am using shiny modules and shinyjs for enabling/disabling the button. However, my current implementation does not disable the button as expected. Here is my implementation:

library(shiny)
library(shinyjs)

mod_1_ui <- function(id) {
  ns <- NS(id)
  
  fluidRow(
    column(
      width = 3,
      radioButtons(
        ns("dist"),
        "Distribution type:",
        c(
          "Normal" = "norm",
          "Uniform" = "unif",
          "Log-normal" = "lnorm",
          "Exponential" = "exp"
        )
      ),
      actionButton(
        inputId = ns("btn_go"),
        label = "Go !",
        icon = icon("play")
      )
    ),
    column(
      width = 9,
      mod_2_ui(ns("display_plot"))
    )
  )
}

mod_1_server <- function(id, r_global) {
  moduleServer(id, function(input, output, session) {
    show <- reactive({
      input$btn_go
    })
    
    mod_2_server("display_plot", show = show, btn_go_id = session$ns("btn_go"), dist = reactive({ input$dist }))
  })
}

mod_2_ui <- function(id) {
  ns <- NS(id)
  
  plotOutput(outputId = ns("plot"))
}

mod_2_server <- function(id, show, btn_go_id, dist) {
  moduleServer(id, function(input, output, session) {
    
    observeEvent(dist(), {
      print(dist())  # Debugging output to check reactive value
      if (dist() == "lnorm") {
        shinyjs::disable(id = session$ns("btn_go"))  # Trying to disable the button
      } else {
        shinyjs::enable(id = session$ns("btn_go"))
      }
    })
    
    observeEvent(show(), {
      output$plot <- renderPlot({
        plot(runif(10, runif(10)))
      })
    })
    
  })
}

ui <- fluidPage(
  useShinyjs(),  # Required for shinyjs to work
  mod_1_ui("mod")
)

server <- function(input, output, session) {
  r_global <- reactiveValues()
  
  mod_1_server("mod", r_global = r_global)
}

if (interactive()) {
  shinyApp(ui, server)
}

How can I properly disable the "Go!" button when "Log-normal" is selected in this modularized Shiny app?

Share asked Mar 3 at 20:50 nimliugnimliug 4652 silver badges17 bronze badges 2
  • No, here is an example with the radiobutton but in my real case, my condition is something available only in the server part. Complicated for me to use an uioutput to deal with that. – nimliug Commented Mar 3 at 21:06
  • For the given example you could use a conditional panel like conditionalPanel( condition = paste0("input['", ns("dist"), "'] != 'lnorm'"), actionButton( inputId = ns("btn_go"),label = "Go !", icon = icon("play") ) ) to hide the button completely without any server handling needed, even though this is probably not what you want. – Tim G Commented Mar 3 at 21:28
Add a comment  | 

1 Answer 1

Reset to default 3

You can use

shinyjs::disable(id = btn_go_id, asis = TRUE)

Explanation:

  • The button id btn_go_id is already passed into mod_2_server and can be used as it is.

  • asis = TRUE is needed because otherwise the shinyjs function honors the namespace. From ?shinyjs::disable:

    asis
    If TRUE, use the ID as-is even when inside a module (instead of adding the namespace prefix to the ID).

发布评论

评论列表(0)

  1. 暂无评论