Simply call shinyalert() with the desired arguments, such as a title and text, and a modal will show up. In order to be able to call shinyalert() in a Shiny app, you must first call useShinyalert() anywhere in the app's UI.
To add an input in a Shiny app, we need to place an input function *Input() in the ui object. Each input function requires several arguments. The first two are inputId , an id necessary to access the input value, and label which is the text that appears next to the input in the app.
shinyApp is a function that builds Shiny apps. You can use shinyApp to define a complete app in a single R script, or even at the command line. shinyApp builds an app from two arguments that parallel the structure of a standard Shiny app.
I'm already using a simpler and more reliable way than the one I posted before.
A combination of
tags$style(type="text/css", "
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: #000000;
background-color: #CCFF66;
z-index: 105;
}
")
with
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div("Loading...",id="loadmessage")
)
Example:
runApp(list(
ui = pageWithSidebar(
headerPanel("Test"),
sidebarPanel(
tags$head(tags$style(type="text/css", "
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: #000000;
background-color: #CCFF66;
z-index: 105;
}
")),
numericInput('n', 'Number of obs', 100),
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div("Loading...",id="loadmessage"))
),
mainPanel(plotOutput('plot'))
),
server = function(input, output) {
output$plot <- renderPlot({ Sys.sleep(2); hist(runif(input$n)) })
}
))
tags$head() is not required, but it's a good practice to keep all the styles inside head tag.
Very simply, you can use built-in shiny functions showModal()
at the start of the function and removeModal()
at the end. If you remove the footer, said modal cannot be clicked out of.
Example:
observeEvent(input$button, {
showModal(modalDialog("Doing a function", footer=NULL))
#Do the stuff here....
#...
#...
#Finish the function
removeModal()
})
I solved the problem by adding the following code to sidebarPanel():
HTML('<script type="text/javascript">
$(document).ready(function() {
$("#DownloadButton").click(function() {
$("#Download").text("Loading...");
});
});
</script>
')
You can use ShinyJS: https://github.com/daattali/shinyjs
When the actionButton is pressed, you can easily toggle a text component showing "loading...", and when the calculation is finished, you can then toggle this component to hidden.
Though this question is old I think it is still relevant. I have another solution to offer that displays the activity indicator on the button that starts a lengthy process next to the button label.
We need an action button with a label in a span
and some way of identifying that label.
actionButton("btnUpdate", span("Update", id="UpdateAnimate", class=""))
We also need some CSS animation that can be added to the button label, e.g. like this:
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); } }
'))
Now we can use shinyjs
to manipulate the span
class which dynamically adds the animation behind the button label. We add the animation once a user presses the button:
observeEvent(input$btnUpdate, { # User requests update
# ...
shinyjs::addClass(id = "UpdateAnimate", class = "loading dots")
shinyjs::disable("btnUpdate")
# ...
})
When the operation has finished we can remove the class from the span and end the animation:
output$distPlot <- renderPlot({
# ...
Sys.sleep(1) # just for show, you probably want to remove it in a real app
# Button settings
shinyjs::enable("btnUpdate")
shinyjs::removeClass(id = "UpdateAnimate", class = "loading dots")
# ...
})
The full code of the sample app is available as gist on GitHub.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With