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.

 1library(shiny)
 2library(shinyjs)
 3library(shinyWidgets)
 4
 5jscode <- '
 6  shinyjs.setbutton = function(params) {
 7    var defaultParams = {
 8      id: null,
 9      button: null
10    };
11    params = shinyjs.getParams(params, defaultParams);
12    var el = $("#" + params.id);
13    var button = $("#" + params.button);
14    el.keyup(function(event) {
15      if (event.keyCode === 13) {
16        button.click();
17      }
18    })
19  };'
20
21ui <- fluidPage(
22  useShinyjs(),
23  extendShinyjs(text = jscode, functions = c('setbutton')),
24  tags$head(tags$script(HTML(jscode))),
25  fluidRow(
26    br(),
27    column(4, offset = 4, uiOutput('loginpanel')),
28    br(),
29    verbatimTextOutput('txtout')
30  )
31)
32
33
34server <- function(input, output, session) {
35  
36  ## reactiveValue to hold username and password
37  out <- reactiveValues(user = NULL, pw = NULL)
38  
39  output$loginpanel <- renderUI({
40    panel(heading = 'login', status = 'danger',
41          selectInput('user', label = NULL, choices = c('bob', 'ben', 'bill')),
42          textInput('txt1', label = 'textbox', value =''),  ## textbox to show that hitting Enter here has no effect
43          uiOutput('pw'),
44          actionBttn('butLogin', label = 'login', style = 'simple', color = 'success'))
45  })
46  
47  output$pw <- renderUI({
48    passwordInput('pwinp', label = NULL)
49  }) 
50  
51  ## attach an event to the passwordInput after a delay to ensure that the widget has been rendered
52  delay(100, 
53        js$setbutton('pw', 'butLogin')
54  )
55
56  ## triggered when button pressed or Enter key when focussed on passwordInput widget
57  observeEvent(input$butLogin, {
58    out$user <- input$user
59    out$pw <- input$pwinp
60  })
61  
62  output$txtout <- renderPrint({
63    paste(out$user, out$pw)
64  })
65}
66
67shinyApp(ui = ui, server = server)