6

Is it possible to disable a button in shiny while a plot / a reactive element is loading? I know shinyjs can disable and enable input elements, but I don't know how to set up the connection to a loading plot / reactive element. The example is based on the Single-file shiny apps page. I just added a button and the isolated part. Solutions that are not based on shinyjs are also appreciated :)

library(shiny)
server <- function(input, output) {
  output$distPlot <- renderPlot({
    input$button

    isolate(
      hist(rnorm(input$obs), col = 'darkgray', border = 'white')
    )
  })
}

ui <- fluidPage(
  shinyjs::useShinyjs(),
  sidebarLayout(
    sidebarPanel(
      sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100),
      actionButton("button", "OK!")
    ),
    mainPanel(plotOutput("distPlot"))
  )
)

shinyApp(ui = ui, server = server)
Felix Grossmann
  • 1,224
  • 1
  • 11
  • 30
  • Another simple approach is to [use req](https://shiny.rstudio.com/articles/req.html) so it will not act when some data is not ready, if that fit your need. – dracodoc May 12 '17 at 20:55

2 Answers2

6

Something like this?

library(shiny)
library(shinyjs)
server <- function(input, output) {

  PlotData <- eventReactive(input$button,{
    disable("button") 
    Sys.sleep(2)
    hist(rnorm(input$obs), col = 'darkgray', border = 'white')
    enable("button") 
  })

  output$distPlot <- renderPlot({
    PlotData()
  })
}

ui <- fluidPage(
  shinyjs::useShinyjs(),
  sidebarLayout(
    sidebarPanel(
      sliderInput("obs", "Number of observations:", min = 10, max = 1000, value = 2000),
      actionButton("button", "OK!")
    ),
    mainPanel(plotOutput("distPlot"))
  )
)

shinyApp(ui = ui, server = server)
Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • Yes, that's exactly what I was looking for! Didn't know that a plot can be part of `eventReactive`. Thanks for your fast response! – Felix Grossmann May 12 '17 at 16:09
6

In the following way you don't have to set a time. The button is disabled only during the calculation.

library(shiny)

js <- "
$(document).ready(function() {
  $('#distPlot').on('shiny:recalculating', function() {
    $('button').prop('disabled', true);
    $('button').css('color', 'red');
  });
  $('#distPlot').on('shiny:recalculated', function() {
    $('button').prop('disabled', false);
    $('button').css('color', 'black');
});
});
"

server <- function(input, output) {

  output$distPlot <- renderPlot({
    hist(rnorm(input$obs), col = 'darkgray', border = 'white')
  })
}

ui <- fluidPage(
  tags$head(tags$script(HTML(js))),
  sidebarLayout(
    sidebarPanel(
      sliderInput("obs", "Number of observations:", min = 10000, max = 100000, value = 20000),
      actionButton("button", "OK!")
    ),
    mainPanel(plotOutput("distPlot"))
  )
)

shinyApp(ui = ui, server = server)
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225