1

I have been using the approach suggested by @wch on SO to close the browser window when clicking an action button in a Shiny app. Works great.

I would now like to stop my app and close the bowser window (in Chrome) when clicking an element in the navbar. Below the tabPanel call I'm using

tabPanel(title = "", value = "Stop", icon = icon("power-off"))

I use an observer to stop the app when the value of input$navbar == "Stop" (i.e, when the icon in the navbar is selected) but I'm not sure how to activate the window.close() call.

Code for action button to close browser windows by @wch

tags$button(
  id = 'close',
  type = "button",
  class = "btn action-button",
  onclick = "window.close();",
  "Close window"
)

EDIT:

Found a work-around that does what I want.

tabPanel(tags$a(id = "quitApp", href = "#", class = "action-button",
         list(icon("power-off"), ""), onclick = "window.close();"))

Unfortunately it leads to a rather badly aligned navbar. I asked a related question on the Shiny google group

badly aligned navbar

Community
  • 1
  • 1
Vincent
  • 5,063
  • 3
  • 28
  • 39
  • could you provide a bit more code to have a fully reproducible shiny app please – DeanAttali Jul 13 '15 at 03:00
  • anything wrong/insufficient with the answer I provided? – DeanAttali Jul 13 '15 at 04:44
  • @daattali I like the answer so I up-voted it. However, I would prefer an option that doesn't require a package dependency. That may not be feasible however. – Vincent Jul 13 '15 at 05:32
  • 1
    Sure, you can get away without the package dependency - are you familiar with "session$sendCustomMessage" to call javascript functions? I only used this package because it makes calling JS functions easier and less messy, but you can replicate my solution with sendCustomMessage if you know how to use it – DeanAttali Jul 13 '15 at 05:34
  • @daattali I haven't used sendCustomMessage much. I would happily give you the 'check' for that answer however. – Vincent Jul 13 '15 at 06:09

1 Answers1

8

You can use the shinyjs package to easily call javascript functions, which is essentially all you need to do. Disclaimer: I wrote that package. Here's the code to do what you want:

library(shinyjs)
jscode <- "shinyjs.closewindow = function() { window.close(); }"

runApp(shinyApp(
  ui = tagList(
    useShinyjs(),
    extendShinyjs(text = jscode),
    navbarPage(
      "test",
      id = "navbar",
      tabPanel(title = "tab1"),
      tabPanel(title = "", value = "Stop", icon = icon("power-off"))
    )
  ),
  server = function(input, output, session) {
    observe({
      if (input$navbar == "Stop") {
        js$closewindow();
        stopApp()
      }
    })
  }
))

EDIT:

If you don't want to use a JS package, you can do the same thing with native shiny:

jscode <- "Shiny.addCustomMessageHandler('closeWindow', function(m) {window.close();});"

runApp(shinyApp(
  ui = tagList(
    tags$head(tags$script(HTML(jscode))),
    navbarPage(
      "test",
      id = "navbar",
      tabPanel(title = "tab1"),
      tabPanel(title = "", value = "Stop", icon = icon("power-off"))
    )
  ),
  server = function(input, output, session) {
    observe({
      if (input$navbar == "Stop") {
        session$sendCustomMessage(type = "closeWindow", message = "message")
        stopApp()
      }
    })
  }
))
DeanAttali
  • 25,268
  • 10
  • 92
  • 118