Mimic Button Press with Enter Key

Sometimes it’s useful to mimic a button press in a shiny app when the Enter key is pressed, for example when entering a password. This has been documented before and works well for most situations but fails when the button widget is housed within renderUI. Here’s an alternative that works wherever the password input and button are located.


library(shiny)
library(shinyjs)
library(shinyWidgets)

jscode <- '
  shinyjs.setbutton = function(params) {
    var defaultParams = {
      id: null,
      button: null
    };
    params = shinyjs.getParams(params, defaultParams);
    var el = $("#" + params.id);
    var button = $("#" + params.button);
    el.keyup(function(event) {
      if (event.keyCode === 13) {
        button.click();
      }
    })
  };'

ui <- fluidPage(
  useShinyjs(),
  extendShinyjs(text = jscode, functions = c('setbutton')),
  tags$head(tags$script(HTML(jscode))),
  fluidRow(
    br(),
    column(4, offset = 4, uiOutput('loginpanel')),
    br(),
    verbatimTextOutput('txtout')
  )
)


server <- function(input, output, session) {
  
  ## reactiveValue to hold username and password
  out <- reactiveValues(user = NULL, pw = NULL)
  
  output$loginpanel <- renderUI({
    panel(heading = 'login', status = 'danger',
          selectInput('user', label = NULL, choices = c('bob', 'ben', 'bill')),
          textInput('txt1', label = 'textbox', value =''),  ## textbox to show that hitting Enter here has no effect
          uiOutput('pw'),
          actionBttn('butLogin', label = 'login', style = 'simple', color = 'success'))
  })
  
  output$pw <- renderUI({
    passwordInput('pwinp', label = NULL)
  }) 
  
  ## attach an event to the passwordInput after a delay to ensure that the widget has been rendered
  delay(100, 
        js$setbutton('pw', 'butLogin')
  )

  ## triggered when button pressed or Enter key when focussed on passwordInput widget
  observeEvent(input$butLogin, {
    out$user <- input$user
    out$pw <- input$pwinp
  })
  
  output$txtout <- renderPrint({
    paste(out$user, out$pw)
  })
}

shinyApp(ui = ui, server = server)

Harvey Lieberman

Written by

Updated