|
| 1 | +--- |
| 2 | +title: "Using keys to navigate" |
| 3 | +output: rmarkdown::html_vignette |
| 4 | +vignette: > |
| 5 | + %\VignetteIndexEntry{Using keys to navigate} |
| 6 | + %\VignetteEngine{knitr::rmarkdown} |
| 7 | + %\VignetteEncoding{UTF-8} |
| 8 | +--- |
| 9 | + |
| 10 | +```{r, include = FALSE} |
| 11 | +knitr::opts_chunk$set( |
| 12 | + collapse = TRUE, |
| 13 | + comment = "#>" |
| 14 | +) |
| 15 | +``` |
| 16 | + |
| 17 | +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 <kbd>?</kbd>. |
| 18 | + |
| 19 | +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: |
| 20 | + |
| 21 | +```{r setup} |
| 22 | +library(keys) |
| 23 | +library(shiny) |
| 24 | +``` |
| 25 | + |
| 26 | +Next, we define the UI part of our app: |
| 27 | + |
| 28 | +```{r ui definition} |
| 29 | +ui <- fluidPage( |
| 30 | + useKeys(), |
| 31 | + keysInput("keys", c("1", "2", "3")), |
| 32 | + tabsetPanel( |
| 33 | + id = "tabs", |
| 34 | + tabPanel("Tab 1", "We're on tab 1"), |
| 35 | + tabPanel("Tab 2", "We're on tab 2"), |
| 36 | + tabPanel("Tab 3", "We're on tab 3") |
| 37 | + ) |
| 38 | +) |
| 39 | +``` |
| 40 | + |
| 41 | +This interface has 3 components: |
| 42 | + |
| 43 | +1. Javascript dependencies |
| 44 | +2. A `keys` input with some defined hotkeys |
| 45 | +3. A `tabsetPanel` |
| 46 | + |
| 47 | +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. |
| 48 | + |
| 49 | +The last step is to write the server logic: |
| 50 | + |
| 51 | +```{r server logic} |
| 52 | +server <- function(input, output, session) { |
| 53 | + observeEvent(input$keys, { |
| 54 | + switch (input$keys, |
| 55 | + "1" = updateTabsetPanel(session, "tabs", "Tab 1"), |
| 56 | + "2" = updateTabsetPanel(session, "tabs", "Tab 2"), |
| 57 | + "3" = updateTabsetPanel(session, "tabs", "Tab 3") |
| 58 | + ) |
| 59 | + }) |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +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: |
| 64 | + |
| 65 | +```{r ui definition with tab values, eval=FALSE} |
| 66 | +tabPanel("Tab 1", "We're on tab 1", value = "1") |
| 67 | +tabPanel("Tab 2", "We're on tab 2", value = "2") |
| 68 | +tabPanel("Tab 3", "We're on tab 3", value = "3") |
| 69 | +``` |
| 70 | + |
| 71 | +The server would then be simplified to: |
| 72 | + |
| 73 | +```{r simplified server, eval=FALSE} |
| 74 | +observeEvent(input$keys, { |
| 75 | + updateTabsetPanel(session, "tabs", input$keys) |
| 76 | +}) |
| 77 | +``` |
| 78 | + |
| 79 | +This is pretty much all you need to start using `keys` for conditional logic in your app. With functions like `addKeys`, `removeKeys`, `recordKeys`, and more, you can be even more creative with the logic. |
| 80 | + |
| 81 | +Lastly, below is the full scripts for both apps demonstrated above: |
| 82 | + |
| 83 | +```{r full scripts, eval=FALSE} |
| 84 | +# without tab values assigned |
| 85 | +library(keys) |
| 86 | +library(shiny) |
| 87 | +
|
| 88 | +ui <- fluidPage( |
| 89 | + useKeys(), |
| 90 | + keysInput("keys", c("1", "2", "3")), |
| 91 | + tabsetPanel( |
| 92 | + id = "tabs", |
| 93 | + tabPanel("Tab 1", "We're on tab 1"), |
| 94 | + tabPanel("Tab 2", "We're on tab 2"), |
| 95 | + tabPanel("Tab 3", "We're on tab 3") |
| 96 | + ) |
| 97 | +) |
| 98 | +
|
| 99 | +server <- function(input, output, session) { |
| 100 | + observeEvent(input$keys, { |
| 101 | + switch (input$keys, |
| 102 | + "1" = updateTabsetPanel(session, "tabs", "Tab 1"), |
| 103 | + "2" = updateTabsetPanel(session, "tabs", "Tab 2"), |
| 104 | + "3" = updateTabsetPanel(session, "tabs", "Tab 3") |
| 105 | + ) |
| 106 | + }) |
| 107 | +} |
| 108 | +
|
| 109 | +shinyApp(ui, server) |
| 110 | +
|
| 111 | +# with tab values assigned |
| 112 | +library(keys) |
| 113 | +library(shiny) |
| 114 | +
|
| 115 | +ui <- fluidPage( |
| 116 | + useKeys(), |
| 117 | + keysInput("keys", c("1", "2", "3")), |
| 118 | + tabsetPanel( |
| 119 | + id = "tabs", |
| 120 | + tabPanel("Tab 1", "We're on tab 1", value = "1"), |
| 121 | + tabPanel("Tab 2", "We're on tab 2", value = "2"), |
| 122 | + tabPanel("Tab 3", "We're on tab 3", value = "3") |
| 123 | + ) |
| 124 | +) |
| 125 | +
|
| 126 | +server <- function(input, output, session) { |
| 127 | + observeEvent(input$keys, { |
| 128 | + updateTabsetPanel(session, "tabs", input$keys) |
| 129 | + }) |
| 130 | +} |
| 131 | +
|
| 132 | +shinyApp(ui, server) |
| 133 | +``` |
0 commit comments