Delaying R Shiny textInput processing

Delay textInput processing until submit button or enter key are pressed, with example Shiny app to fetch METAR data.
R
Code Snippet
Published

March 11, 2025

In a typical R Shiny app, as soon as anything is entered in a textInput field, processing is started (even if you haven’t finished typing). I wanted to fetch METAR airport weather data from the Aviation Weather Center API, but wanted to make sure the request wasn’t made until I was ready.

One option is to use an actionButton Submit button, but I wanted the app to respond to pressing <enter> after entering the airport ID as another option.

All that’s needed is a snippet of JavaScript code (solution from here) that clicks the submit button when the enter key is pressed when the specific textInput field has focus. Here’s the JavaScript:

$(document).keyup(function(event) {
    if ($("#airport_id").is(":focus") && (event.key == "Enter")) {
        $("#submit_btn").click();
    }
});

Replace #airport_id with your textInput ID and #submit_btn with you actionButton ID.

Example Shiny app to fetch METAR data

Fetch current METAR for an airport whose ICAO ID is entered into a textInput field. The data is only requested when either the submit button is pressed or the enter key is pressed while in the textInput field.

It’d be better style to import the JavaScript from a separate file script.js, but I wanted this example code to all be in one place. To do it that way, place the JavaScript file in a www directory at the same level as app.R. Then, anywhere within the Shiny app, import it with with tags$script(src = "script.js")

library(shiny)
library(rvest)

ui <- fluidPage(
  tags$script(
    HTML(
      '$(document).keyup(function(event) {
          if ($("#airport_id").is(":focus") && (event.key == "Enter")) {
              $("#submit_btn").click();
          }
        });'
    )),
  textInput(
    inputId = "airport_id",
    label = "Airport ICAO identifier:",
    value = "kowd,khya,korh,kpym,k1b9,ksfz,kbed,kbos"),
  actionButton("submit_btn", "Fetch METAR"),
  tags$hr(),
  verbatimTextOutput("metar")
)

server <- function(input, output, session) {
  observeEvent(input$submit_btn, {
    tryCatch(
      {
        url <- paste0("https://aviationweather.gov/api/data/metar?ids=", input$airport_id)
        metar <- rvest::read_html(url) |> html_element("p") |> html_text() # html_text2() strips \n
        output$metar <- renderText(metar)
      },
      error = function(cond) {
        output$metar <- renderText("ERROR: unable to fetch METAR")
      }
    )
  })
}

shinyApp(ui, server)

Example output