# Using keys to navigate

Navigating a web app without pointing and clicking is common in many popular websites. For example, GitHub has a number of hotkeys, all of which can be viewed by pressing `?`.

The same functionality can be used in shiny apps with `keys`. In this vignette, we’ll go over a small example that demonstrates how you can use `keys` to navigate a shiny app with tabs. First we start by loading the required packages:

    library(keys)
    library(shiny)

Next, we define the UI part of our app:

    ui <- fluidPage(
      useKeys(),
      keysInput("keys", c("1", "2", "3")),
      tabsetPanel(
        id = "tabs",
        tabPanel("Tab 1", "We're on tab 1"),
        tabPanel("Tab 2", "We're on tab 2"),
        tabPanel("Tab 3", "We're on tab 3")
      )
    )

This interface has 3 components:

1. Javascript dependencies
2. A `keys` input with some defined hotkeys
3. A `tabsetPanel`

It’s important to note that the `tabsetPanel` has an ID assigned to it. An ID must be assigned to a `tabsetPanel` in order to observe which tab is active from the server, `?tabsetPanel` will give some additional detail on this.

The last step is to write the server logic:

    server <- function(input, output, session) {
      observeEvent(input$keys, {
        switch (input$keys,
          "1" = updateTabsetPanel(session, "tabs", "Tab 1"),
          "2" = updateTabsetPanel(session, "tabs", "Tab 2"),
          "3" = updateTabsetPanel(session, "tabs", "Tab 3")
        )
      })
    }

With this, we can observe which hotkeys the user presses and then update which tab is active. We could even bypass the `switch` call by providing a `value` to each `tabPanel` that corresponds with the hotkeys:

    tabPanel("Tab 1", "We're on tab 1", value = "1")
    tabPanel("Tab 2", "We're on tab 2", value = "2")
    tabPanel("Tab 3", "We're on tab 3", value = "3")

The server would then be simplified to:

    observeEvent(input$keys, {
      updateTabsetPanel(session, "tabs", input$keys)
    })

This is pretty much all you need to start using `keys` for conditional logic in your app. If you’re looking for more advanced logic, you can be creative with functions like `addKeys`, `removeKeys`, and `recordKeys`.

Finally, below is the full scripts for both apps demonstrated above:

    # without tab values assigned
    library(keys)
    library(shiny)

    ui <- fluidPage(
      useKeys(),
      keysInput("keys", c("1", "2", "3")),
      tabsetPanel(
        id = "tabs",
        tabPanel("Tab 1", "We're on tab 1"),
        tabPanel("Tab 2", "We're on tab 2"),
        tabPanel("Tab 3", "We're on tab 3")
      )
    )

    server <- function(input, output, session) {
      observeEvent(input$keys, {
        switch (input$keys,
          "1" = updateTabsetPanel(session, "tabs", "Tab 1"),
          "2" = updateTabsetPanel(session, "tabs", "Tab 2"),
          "3" = updateTabsetPanel(session, "tabs", "Tab 3")
        )
      })
    }

    shinyApp(ui, server)

    # with tab values assigned
    library(keys)
    library(shiny)

    ui <- fluidPage(
      useKeys(),
      keysInput("keys", c("1", "2", "3")),
      tabsetPanel(
        id = "tabs",
        tabPanel("Tab 1", "We're on tab 1", value = "1"),
        tabPanel("Tab 2", "We're on tab 2", value = "2"),
        tabPanel("Tab 3", "We're on tab 3", value = "3")
      )
    )

    server <- function(input, output, session) {
      observeEvent(input$keys, {
        updateTabsetPanel(session, "tabs", input$keys)
      })
    }

    shinyApp(ui, server)