闪亮响应进入

Shiny Responds to Enter

我有一个 textInput 小部件,现在每当我开始在该小部件中键入内容时,shinyApp 都会尝试评估 textInput 小部件中未完成的内容,并导致许多错误。我知道添加一个操作 Button "Calculate" 可以轻松解决问题。但是,我的应用程序没有 space 剩下一个按钮。所以,我想知道是否有一种方法可以让 textInput 小部件 "listen" 响应键盘事件,例如当用户点击 "Enter?" 提前致谢!

在你的情况下,问题是反应式编程,这就是你需要一些东西来管理这种情况的原因。我的建议是使用 observer pattern or validate function.

  • 观察者模式: shiny 实现了观察者模式 当对象中发生事件时(可以是单击 在按钮中,输入中的新值...)。

  • 验证函数:这个过程的功能类似于 if/else 声明。的确,需要如果检查 参数,如果值不对,会有错误提示。

想知道如何使用observe pattern和validate函数,点击前面的link(在Shiny网站上都有解释)

这是我构建的一个应用程序,解决了类似的问题。

我们的想法是同时聆听按键和按钮的声音,并确保它们能够很好地协同工作。在你的情况下,你应该能够使事情变得更简单,因为你不需要按钮。

希望大家喜欢

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 = ", ")
      # })
    }
  )
)

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

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

很好的问题。这是我使用方式的示例;这个应用程序显示一个 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())
})