Michael Bird
Michael Bird

Reputation: 783

Shiny - Detect a change in input with a warning in Ui.R

I have an app that has many inputs and that uses an actionButton() to do some calculation that takes a non trivial amount of time including reading some files and plotting a map.

During some user testing, some of the feedback that the need to re-press the actionButton() after adjusting an input was non intuitive. I would like to render a warning message (read "helpful reminder") that users need re-press the actionButton(). I'd like it if this message only rendered after inputs are changed since the last press of the actionButton().

So far I have tried using global variables inside an 'eventReactive()' and trying to use identical() with no luck.

My question is: How can I render a helpful reminder to re-press an actionButton() when any inputs have changed since last time the button was pressed?.

Here is a minimal example of an app with many inputs that takes some time to output something

## app.R ##
library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    #arbritray inputs
    sliderInput("in1", label = "Input 1", value=1,min=0,max=5),
    sliderInput("in2", label = "Input 2", value=2,min=0,max=5),
    sliderInput("in3", label = "Input 3", value=3,min=0,max=5),
    actionButton("StartCalculation","Calculate")
  ),
  dashboardBody(
    textOutput("answer")
  )
)

server <- function(input, output) {

  out <- eventReactive(input$StartCalculation,{
        Sys.sleep(2) #simulate long computation
    input$in1+input$in2+input$in3
  })

  output$answer <- renderText({
    out()
  })
}

shinyApp(ui, server)

Upvotes: 3

Views: 2925

Answers (1)

Gregor de Cillia
Gregor de Cillia

Reputation: 7655

You can use reactiveVal inside your server to save the "status" (changed or unchanged). Just make sure that the status gets updated whenever either the button is pressed or inputs change.

library(shiny)
library(shinydashboard)

ui <- fluidPage(
  inputPanel(
    #arbritray inputs
    sliderInput("in1", label = "Input 1", value=1,min=0,max=5),
    sliderInput("in2", label = "Input 2", value=2,min=0,max=5),
    sliderInput("in3", label = "Input 3", value=3,min=0,max=5),
    actionButton("StartCalculation","Calculate")
  ),
  textOutput("answer"),
  textOutput("status")
)

server <- function(input, output) {
  status <- reactiveVal()

  out <- eventReactive(input$StartCalculation,{
    status("up to date")
    Sys.sleep(2) #simulate long computation
    input$in1+input$in2+input$in3
  })

  observeEvent({list(input$in1,input$in2,input$in3)},
               {status("Needs recalculation")})

  output$answer <- renderText({out()})

  output$status <- renderText({status()})
}

shinyApp(ui, server)

Upvotes: 6

Related Questions