Reputation: 73
I'm building an app with several tabs, some which involve excessive calculations and others that calculate quickly. A checkbox which would allow the user to choose between reactivity or manual updating, in combination with a "refresh"-button, would be ideal.
The simple example below illustrates what I'm aiming for. It nearly works, except for one final refresh when the "Automatically refresh"-checkbox is unchecked, which is a pain, should a computationally intensive tab be open. Is there any way around this?
ui.r
library(shiny)
shinyUI(fluidPage(
titlePanel("Test"),
sidebarLayout(
sidebarPanel(
checkboxInput("autoRefresh", "Automatically refresh", TRUE),
actionButton("refresh", "Refresh!"),
radioButtons("choice", "Choice of value:",
c("10" = 10,
"20" = 20))
),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Add random decimals to value", textOutput("value"))
)
)
)
))
server.r
library(shiny)
shinyServer(function(input, output) {
output$value <- renderText({
input$refresh
if(input$autoRefresh == 1) {
input$choice
}
isolate({
output <- runif(1,0,1) + as.numeric(input$choice)
})
})
})
Many thanks in advance!
Upvotes: 7
Views: 232
Reputation: 12664
In this solution, I made two observers: one for when the refresh
button is hit and a second for when choice
is changed. The first always updates the output.
The second checks the status of input$autoRefresh
and then either just exits or updates the renderText
.
Unfortunately you must have the runif
command written twice, which can be bad for updating your code (easier to introduce errors if you are doing something twice). In practice you might want to make a new function and then just call that function if this is a complex/multi-line process in your actual app.
shinyServer(function(input, output) {
observe({
input$refresh
output$value<-renderText({
isolate(runif(1,0,1) + as.numeric(input$choice))
})
})
observe({
input$choice
output$value<-if(input$autoRefresh==0) return() else {
renderText({isolate(runif(1,0,1) + as.numeric(input$choice))})
}
})
})
Upvotes: 2
Reputation: 2394
You could cache the output and shortcut-return it when appropriate
library(shiny)
shinyServer(function(input, output) {
output$value <- renderText({
input$refresh
if(input$autoRefresh == 1) {
input$choice
} else return(cachedOutput)
isolate({
cachedOutput <<- output <- runif(1,0,1) + as.numeric(input$choice)
})
})
})
Upvotes: 2