I have a complex shiny app with a lot of inputs, a leaflet map etc ... The problem I have is when the app is busy making some calculations, the users keep on clicking anywhere on the app, and sometimes the app crash.
I would like to prevent the users from making any click when the app is busy. It is important that the spinner stays a spinner and not a full page waiter like in the waiter
package. Maybe there is a possibility to combine a spinner and waiter ? But I did'nt find out yet how to.
I have a small reprex here : When i click one the button "busy app", there is a 5 seconds spinner to make the user wait. But during this time, the user can still click on "increment" button. And at the end of the spinner, the output increments by the number of clicks that where made. I would like to block the whole app to the user at once, not just put a "disable" on the button when the app is busy (because I have lots of input in my app and that would require too much modifications)
library(shiny)
ui <- fluidPage(
# spinner css
tags$head(
tags$style(HTML("
#loadmessage {
position:fixed; z-index:8; top:50%; left:50%; padding:10px;
text-align:center; font-weight:bold; color:#000000; background-color:#CCFF66;
}
.loader {
position:fixed; z-index:8; border:16px solid #999999;
border-top: 16px solid #8B0000; border-radius: 50%;
width: 120px; height: 120px; top:45%; left:45%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}"))
),
# display load spinner when shiny is busy
conditionalPanel(
condition = "$(\'html\').hasClass(\'shiny-busy\')",
tags$div(class = "loader")
),
actionButton(
inputId = "increment",
label = "Increment"
),
textOutput("result"),
actionButton(
inputId = "busy",
label = "Busy app"
)
)
server <- function(input, output, session) {
rv <- reactiveValues(counter = 0)
#increment counter
observeEvent(input$increment,{
rv$counter = rv$counter + 1
})
#display incremented counter
output$result <- renderText({
rv$counter
})
observeEvent(input$busy, {
Sys.sleep(5)
# during this time, the user should not be able to do anything on the app
})
}
shinyApp(ui = ui, server = server)