--- title: "Using keys to navigate" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Using keys to navigate} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` Navigating a web app without pointing and clicking is common in many popular websites. For example, GitHub has a number of [hotkeys](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/keyboard-shortcuts), 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: ```{r setup} library(keys) library(shiny) ``` Next, we define the UI part of our app: ```{r ui definition} 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: ```{r 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: ```{r ui definition with tab values, eval=FALSE} 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: ```{r simplified server, eval=FALSE} 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: ```{r full scripts, eval=FALSE} # 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) ```