Skip to content

Instantly share code, notes, and snippets.

@SigurdJanson
Last active May 11, 2021 17:38
Show Gist options
  • Save SigurdJanson/e2fb39c90d46c0526829c59713f27c50 to your computer and use it in GitHub Desktop.
Save SigurdJanson/e2fb39c90d46c0526829c59713f27c50 to your computer and use it in GitHub Desktop.
How to display an activity indicator on a button to tell users that the app is busy with handling request (shiny, R)
# This sample shows how to display an activity indicator on a button to tell users that
# the app is busy with handling their recent request.
#
# The activity indicator works with CSS only.
#
# Based on the template project "Shiny Web Application" of RStudio.
# The difference is that the chart is not updated as soon as a user changes the bins slider but
# rather waits until an update is explicitely request through a button press.
# The CSS animation has been taken from https://maxbeier.github.io/text-spinners/
library(shiny)
library(shinyjs)
# Define UI for application that draws a histogram
ui <- fluidPage(
useShinyjs(),
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
),
# Show a plot of the generated distribution
mainPanel(
tags$head(tags$style(type="text/css", '
.loading {
display: inline-block;
overflow: hidden;
height: 1.3em;
margin-top: -0.3em;
line-height: 1.5em;
vertical-align: text-bottom;
box-sizing: border-box;
}
.loading.dots::after {
text-rendering: geometricPrecision;
content: "⠋\\A⠙\\A⠹\\A⠸\\A⠼\\A⠴\\A⠦\\A⠧\\A⠇\\A⠏";
animation: spin10 1s steps(10) infinite;
animation-duration: 1s;
animation-timing-function: steps(10);
animation-delay: 0s;
animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: none;
animation-play-state: running;
animation-name: spin10;
}
.loading::after {
display: inline-table;
white-space: pre;
text-align: left;
}
@keyframes spin10 { to { transform: translateY(-15.0em); } }
')),
plotOutput("distPlot"),
actionButton("btnUpdate", span("Update", id = "UpdateAnimate", class = "loading dots"))
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
UpdatePlot <- reactiveVal(1)
output$distPlot <- renderPlot({
req(UpdatePlot())
Sys.sleep(1) # just for show
# Button settings
shinyjs::enable("btnUpdate")
shinyjs::removeClass(id = "UpdateAnimate", class = "loading dots")
x <- faithful[, 2]
isolate( # update chart ONLY after button press
bins <- seq(min(x), max(x), length.out = input$bins + 1)
)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
observeEvent(input$btnUpdate, { # User requests update
UpdatePlot(NULL)
shinyjs::addClass(id = "UpdateAnimate", class = "loading dots")
shinyjs::disable("btnUpdate")
UpdatePlot(TRUE)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment