How to stop running shiny app by closing the browser window?
I'm not aware of shinyapps.io, but in R (as your tag shows) you can indeed stop a shinyApp
through the onSessionEnded
. The following is a minimal working example.
rm(list=ls())library(shiny)doshiny <- function() { app=shinyApp( ui = fluidPage( textInput("textfield", "Insert some text", value = "SomeText") ), server = function(input, output, session) { session$onSessionEnded(function() { stopApp() }) } ) runApp(app)}openshiny <- function() { doshiny() print("Finished.")}openshiny()
I found this excellent code which does the job. Basically, you do like so:
library(shiny)library(shinyjs)jscode <- "shinyjs.closeWindow = function() { window.close(); }"ui <- fluidPage( useShinyjs(), extendShinyjs(text = jscode, functions = c("closeWindow")), actionButton("close", "Close window"))server <- function(input, output, session) { observeEvent(input$close, { js$closeWindow() stopApp() })}shinyApp(ui, server)
Note though that closing the browser window through JavaScript may be prohibited. But this is another discussion.
I have added this inactivity
JS code to help me with some of my shiny apps which are IDLE. The code is pretty much self explanatory where I track down the mouse movements and clicks. Note that this app will close after 5 seconds.
library(shiny)library(leaflet)inactivity <- "function idleTimer() { var t = setTimeout(logout, 5000); window.onmousemove = resetTimer; // catches mouse movements window.onmousedown = resetTimer; // catches mouse movements window.onclick = resetTimer; // catches mouse clicks window.onscroll = resetTimer; // catches scrolling window.onkeypress = resetTimer; //catches keyboard actions function logout() { window.close(); //close the window } function resetTimer() { clearTimeout(t); t = setTimeout(logout, 5000); // time is in milliseconds (1000 is 1 second) }}idleTimer();"ui <- fluidPage( tags$script(inactivity), actionButton("recalc","recalc"), leafletOutput("mymap"))server <- shinyServer(function(input,output,session){ points <- eventReactive(input$recalc, { cbind(rnorm(40) * 2 + 13, rnorm(40) + 48) }, ignoreNULL = FALSE) output$mymap <- renderLeaflet({ leaflet() %>% addProviderTiles(providers$Stamen.TonerLite,options = providerTileOptions(noWrap = TRUE)) %>% addMarkers(data = points()) })})runApp(list(ui = ui, server = server))