闪亮回应输入

时间:2015-07-14 19:10:04

标签: r shiny

我有一个textInput小部件,现在每当我开始输入小部件时,shinyApp会尝试评估textInput小部件中未完成的内容并导致许多错误。我知道添加动作按钮“计算”可以轻松解决问题。但是,我的应用程序没有剩余空间再一个按钮。所以,我想知道是否有一种方法可以让textInput小部件“监听”键盘事件,例如当用户点击“Enter?”时提前谢谢!

3 个答案:

答案 0 :(得分:7)

非常好的问题。这是我使用方式的一个例子;这个应用程序显示了一个ggplot,用户在文本框中给出了ggplot的标题 - 但标题更改只有在按下“Return”时才会响应:

js <- '
$(document).on("keyup", function(e) {
  if(e.keyCode == 13){
    Shiny.onInputChange("keyPressed", Math.random());
  }
});
'

shinyApp(
  ui = bootstrapPage(

    tags$script(js),

    textInput("title", label = "Title"),

    plotOutput("ggplot")
  ),

  server = function(input, output, session){

    Title <- reactiveVal()

    observeEvent(input[["keyPressed"]], {
      Title(input[["title"]])
    })

    output[["ggplot"]] <- renderPlot({
      ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) +
        geom_point() +
        ggtitle(Title())
    })

  }
)

说明:

此Javascript代码:

$(document).on("keyup", function(e) {
  if(e.keyCode == 13){
    Shiny.onInputChange("keyPressed", Math.random());
  }
});

创建一个新的Shiny输入,即input$keyPressed,当在任何地方按下“Return”键时,它会收到一个随机数。

然后我定义了一个反应值,它取用了用户在文本框中给出的值input$title,只有在input$keyPressed更改时才会显示:

Title <- reactiveVal()

observeEvent(input[["keyPressed"]], {
  Title(input[["title"]])
})

最后我将此反应值传递给ggtitle

output[["ggplot"]] <- renderPlot({
  ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) +
    geom_point() +
    ggtitle(Title())
})

答案 1 :(得分:3)

这是我构建的应用,并解决了类似的问题。

我们的想法是听取按键和按键,并确保它们能够很好地协同工作。在您的情况下,您应该能够制作更简单的东西,因为您不需要按钮。

我希望你喜欢它。

library(shiny)
# This is a demo app to test a key binding on an actionButton
# Uncommenting the info item (on both UI and server) will display internal stuff
runApp( 
  list(
    #############################################
    # UI 
    #############################################
    ui = bootstrapPage(
      textInput ("myinput", label = "Write something here"),
      tags$script('
        $(document).on("keydown", function (e) {
        Shiny.onInputChange("lastkeypresscode", e.keyCode);
        });
        '),
      actionButton("GO", "Lancer le matching !"),
      # verbatimTextOutput("info"),
      verbatimTextOutput("results")
    ), 

    #############################################
    # SERVER 
    #############################################
    server = function(input, output, session) {

      # There are state variables for the input text and GO button
      curr.val <- "" # Corresponds to the current displayed input$myinput
      curr.go  <- 0  # Corresponds to the last known GO value (integer)

      lastEvent <- reactive({
        # Is reactive to the following events
        input$GO
        input$lastkeypresscode

        # Decide which action should be taken
        if(input$GO > curr.go) {
          # The user pushed the GO actionButton, so take action
          action <- 1
          curr.go <<- input$GO
        } else if(input$lastkeypresscode == 13) {
          # The user pressed the Enter key, so take action
          action <- 1
        } else {
          # The user did anything else, so do nothing
          action <- 0
        }

        return(action)
      })

      output$results = renderPrint({
        if(lastEvent() == 1) {
          curr.val <<- isolate(input$myinput)
        }
        curr.val
      })

      # output$info = renderText({
      #   paste(curr.val, curr.go, input$lastkeypresscode, sep = ", ")
      # })
    }
  )
)

答案 2 :(得分:1)

我创建了一个简单的应用程序作为示例,用户可以在其中写入城市的名称,按ENTER后返回纬度和经度:

library(shiny)
library(ggmap)


runApp( 
  list(
    #############################################
    # UI 
    #############################################
ui = fluidPage( title = "City Search" ,
                position= "static-top",
                tags$script(' $(document).on("keydown", function (e) {
                                                  Shiny.onInputChange("lastkeypresscode", e.keyCode);
                                                  });
                                                  '),
                # Search panel:
                textInput("search_city", "" , placeholder= "City"),
                verbatimTextOutput("results")), 

    #############################################
    # SERVER 
    #############################################
server = function(input, output, session) {

  observe({
    if(!is.null(input$lastkeypresscode)) {
      if(input$lastkeypresscode == 13){
        target_pos = geocode(input$search_city, messaging =FALSE)
        LAT = target_pos$lat
        LONG = target_pos$lon
        if (is.null(input$search_city) || input$search_city == "")
          return()
        output$results = renderPrint({
          sprintf("Longitude: %s ---- Latitude: %s", LONG, LAT)
        })
      }
    }
  })
}
)
)

请注意,为了捕获ENTER输入,代码为13,即input$lastkeypresscode == 13