R Shiny key input binding

In a Shiny application, is it possible to have a binding that listens to what key a user presses down?

I'm not too familiar with JavaScript, but I'm looking for something like:

window.onkeydown = function (e) {
    var code = e.keyCode ? e.keyCode : e.which;
    alert(code);
};

where the key input is then to be used in server.R, e.g.:

shinyServer(function(input, output) {

  output$text <- renderText({
    paste('You have pressed the following key:', input$key)
  })

  # ...

})

Solution 1:

You can add a listener for keypresses. The Shiny.onInputChange can be used to bind the key pressed to a shiny variable:

library(shiny)
runApp( list(ui = bootstrapPage(
  verbatimTextOutput("results"),
  tags$script('
    $(document).on("keypress", function (e) {
       Shiny.onInputChange("mydata", e.which);
    });
  ') 
)
, server = function(input, output, session) {

  output$results = renderPrint({
    input$mydata
  })
}
))

for keydown events you can substitute:

  tags$script('
    $(document).on("keydown", function (e) {
       Shiny.onInputChange("mydata", e.which);
    });
  ') 

Solution 2:

I've been working on an R package {keys} to solve this problem. It's basically a wrapper around the Mousetrap javascript library. With this, observing keys is an easy task:

library(shiny)
library(keys)

hotkeys <- c(
  "1", 
  "command+shift+k", 
  "up up down down left right left right b a enter"
)

ui <- fluidPage(
  useKeys(),
  keysInput("keys", hotkeys)
)

server <- function(input, output, session) {
  observeEvent(input$keys, {
    print(input$keys)
  })
}

shinyApp(ui, server)

More information here: https://github.com/r4fun/keys