I'm trying to build an application where keyboard presses are captured, however I've run into the issue that if the same keyboard presses are used successively then shiny doesn't seem to register the input. Wondering if there is a way around this.
E.g., here's what I mean.
library(shiny)
runApp( list(ui = bootstrapPage(
verbatimTextOutput("results"),
tags$script('
$(document).on("keydown", function (e) {
Shiny.onInputChange("down", e.which);
});'),
tags$script('
$(document).on("keyup", function (e) {
Shiny.onInputChange("up", e.which);
});')
)
, server = function(input, output, session) {
output$results = renderPrint({
print(rnorm(1))
c(input$down, input$up)
})
}
))
Typing/releasing different characters on the keyboard generates new input, hence the random number generator is called when these events occur. But typing, say, 'g'
'g'
'g'
only registers the first up-down keystrokes and ignores the rest.
Shiny.onInputChange
only reacts when the js object it references changes, but the way you've written your js the value is being reassigned to the same thing with multiple presses of the same key.
An ugly workaround might be something like making the variable be the key presses and a random float in an array.
library(shiny)
runApp( list(ui = bootstrapPage(
verbatimTextOutput("results"),
tags$script('
$(document).on("keydown", function (e) {
Shiny.onInputChange("down", [e.which,Math.random()]);
});'),
tags$script('
$(document).on("keyup", function (e) {
Shiny.onInputChange("up", [e.which,Math.random()]);
});')
)
, server = function(input, output, session) {
output$results = renderPrint({
print(rnorm(1))
c(input$down[1], input$up[1])
})
}
))
It might be more efficient to eliminate the need to generate random numbers, and pass some potentially useful information back. For example using the timestamp property you could implement some filtering on the key presses.
library(shiny)
runApp( list(ui = bootstrapPage(
verbatimTextOutput("results"),
tags$script('
$(document).on("keydown", function (e) {
Shiny.onInputChange("down", [e.which,e.timeStamp]);
});'),
tags$script('
$(document).on("keyup", function (e) {
Shiny.onInputChange("up", [e.which,e.timeStamp]);
});')
)
, server = function(input, output, session) {
output$results = renderPrint({
print(rnorm(1))
c(input$down[1], input$up[1])
})
}
))
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