Skip to content

Commit

Permalink
finalize module code-along
Browse files Browse the repository at this point in the history
  • Loading branch information
rpodcast committed Sep 17, 2023
1 parent e3c3561 commit c692672
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"hash": "c88328e0e03c4bc3dae3add79032a6de",
"hash": "3bc604251443b99b15f919abb6ad30ca",
"result": {
"markdown": "---\ntitle: Modules for LEGO attribute selections\n---\n\n\nAs you make the transition to building production Shiny applications, Shiny modules are a very important tool to improve code organization and overall flow of your application. We will work together to build Shiny modules that let the user filter the underlying LEGO metadata based on a key variables in the overall data.\n\n## Requirements\n\nCreste three inputs for the user to subset the LEGO metadata by the following key variables:\n\n* Theme(s) associated with sets. Default should be all sets, but let the user customize selections with a search box.\n* Year range for when set was created. Give the user a visual cue of how many sets are present in each year.\n* Pre-defined ranges for how many parts are present in each set. Ranges are the following:\n + Small (1-50 parts)\n + Medium (51-200 parts)\n + Large (201 or more parts)\n + All sizes\n\n## Data\n\nThe following data sets included in the application contain the variables needed for the requirements (note that these snippets are a reduced sample of each source data set).\n\n### `sets`\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndplyr::glimpse(sets)\n```\n:::\n\n::: {.cell}\n::: {.cell-output .cell-output-stdout}\n\n```\nRows: 368\nColumns: 6\n$ set_num <chr> \"001-1\", \"002-1\", \"1030-1\", \"1038-1\", \"1039-1\", \"1237-1\", \"1…\n$ name <chr> \"Gears\", \"4.5V Samsonite Gears Motor Set\", \"TECHNIC I: Simpl…\n$ year <dbl> 1965, 1965, 1985, 1985, 1986, 2001, 1999, 1999, 1999, 1999, …\n$ theme_id <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …\n$ num_parts <dbl> 43, 3, 210, 120, 39, 56, 30, 29, 28, 26, 28, 103, 98, 64, 28…\n$ img_url <chr> \"https://cdn.rebrickable.com/media/sets/001-1.jpg\", \"https:/…\n```\n\n\n:::\n:::\n\n\n### `themes`\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndplyr::glimpse(themes)\n```\n:::\n\n::: {.cell}\n::: {.cell-output .cell-output-stdout}\n\n```\nRows: 30\nColumns: 3\n$ theme_id <dbl> 191, 708, 693, 398, 650, 234, 56, 604, 136, 736, 692, 676, 2…\n$ name <chr> \"Dark Forest\", \"The LEGO Batman Movie\", \"Monkie Kid\", \"FIRST…\n$ parent_id <dbl> 186, 697, NA, NA, 632, 233, 52, NA, 126, 501, 535, NA, 227, …\n```\n\n\n:::\n:::\n\n\n\n## Plan\n\n1. Create a new module R script (and possible a supporting R script) by using `golem::add_module()` in the `dev/02_dev.R` script.\n1. Pick a Shiny input type that matches our requirements.\n1. Ensure the server-side portion of the module returns the result of the selection, with additional post-processing if necessary.\n1. Plug in the UI and server-side portions of the module in the main `app_ui.R` and `app_server.R` files, respectively.",
"markdown": "---\ntitle: Modules for LEGO attribute selections\nformat:\n html:\n code-line-numbers: false\n---\n\n\nAs you make the transition to building production Shiny applications, Shiny modules are a very important tool to improve code organization and overall flow of your application. We will work together to build Shiny modules that let the user filter the underlying LEGO metadata based on a key variables in the overall data.\n\n## Requirements\n\nCreste three inputs for the user to subset the LEGO metadata by the following key variables:\n\n* Theme(s) associated with sets. Default should be all sets, but let the user customize selections with a search box.\n* Year range for when set was created. Give the user a visual cue of how many sets are present in each year.\n* Pre-defined ranges for how many parts are present in each set. Ranges are the following:\n + Small (1-50 parts)\n + Medium (51-200 parts)\n + Large (201 or more parts)\n + All sizes\n\n## Data\n\nThe following data sets included in the application contain the variables needed for the requirements (note that these snippets are a reduced sample of each source data set).\n\n### `sets`\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndplyr::glimpse(sets)\n```\n:::\n\n::: {.cell}\n::: {.cell-output .cell-output-stdout}\n\n```\nRows: 368\nColumns: 6\n$ set_num <chr> \"001-1\", \"002-1\", \"1030-1\", \"1038-1\", \"1039-1\", \"1237-1\", \"1…\n$ name <chr> \"Gears\", \"4.5V Samsonite Gears Motor Set\", \"TECHNIC I: Simpl…\n$ year <dbl> 1965, 1965, 1985, 1985, 1986, 2001, 1999, 1999, 1999, 1999, …\n$ theme_id <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …\n$ num_parts <dbl> 43, 3, 210, 120, 39, 56, 30, 29, 28, 26, 28, 103, 98, 64, 28…\n$ img_url <chr> \"https://cdn.rebrickable.com/media/sets/001-1.jpg\", \"https:/…\n```\n\n\n:::\n:::\n\n\n### `themes`\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndplyr::glimpse(themes)\n```\n:::\n\n::: {.cell}\n::: {.cell-output .cell-output-stdout}\n\n```\nRows: 30\nColumns: 3\n$ theme_id <dbl> 191, 708, 693, 398, 650, 234, 56, 604, 136, 736, 692, 676, 2…\n$ name <chr> \"Dark Forest\", \"The LEGO Batman Movie\", \"Monkie Kid\", \"FIRST…\n$ parent_id <dbl> 186, 697, NA, NA, 632, 233, 52, NA, 126, 501, 535, NA, 227, …\n```\n\n\n:::\n:::\n\n\n## Plan\n\n1. Create a new module R script (and possible a supporting R script) by using `golem::add_module()` in the `dev/02_dev.R` script.\n1. Pick a Shiny input type that matches our requirements.\n1. Ensure the server-side portion of the module returns the result of the selection, with additional post-processing if necessary.\n1. Plug in the UI and server-side portions of the module in the main `app_ui.R` and `app_server.R` files, respectively.\n\n## Solution (Theme Picker)\n\nCreate the module file with the following snippet:\n\n\n::: {.cell}\n\n```{.r .cell-code}\ngolem::add_module(name = \"theme_picker\", with_test = FALSE)\n```\n:::\n\n\nWhile we could choose a `selectInput` that displays the name of the theme as the choices and allow multiple to be selected, we want to incorporate a search box with snappy performance. The [`virtualSelectInput`](https://dreamrs.github.io/shinyWidgets/reference/virtualSelectInput.html) from the [`{shinyWidgets}`](https://dreamrs.github.io/shinyWidgets/index.html) package is an excellent solution.\n\nSince we have the `themes` data set available, we can also leverage the supporting function `shinyWidgets::prepare_choices()` to get the possible choices ready for the input. The module will simply return the selection as a reactive variable.\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# UI portion\nmod_theme_picker_ui <- function(id, label = NULL) {\n ns <- NS(id)\n\n themes <- dplyr::arrange(themes, name)\n\n choices_list <- shinyWidgets::prepare_choices(\n themes,\n label = name,\n value = theme_id\n )\n\n tagList(\n virtualSelectInput(\n ns(\"virt_theme_id\"),\n label = label,\n choices = choices_list,\n selected = themes$theme_id,\n multiple = TRUE,\n search = TRUE\n )\n )\n}\n\n# server portion\nmod_theme_picker_server <- function(id){\n moduleServer( id, function(input, output, session){\n ns <- session$ns\n\n return(reactive(input$virt_theme_id))\n })\n}\n```\n:::\n\n\nAt the bottom of the module script, `{golem}` automatically includes commented code for referencing the module UI and server blocks in your main Shiny application. We can copy them into the `app_ui.R` and `app_server.R` files.\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# app_ui.R\nmod_theme_picker_ui(\"theme_picker_1\")\n\n# app_server.R\ninput_theme_ids <- mod_theme_picker_server(\"theme_picker_1\")\n```\n:::\n",
"supporting": [
"codealong-1_files"
],
Expand Down
71 changes: 69 additions & 2 deletions materials/d1-02-structure/codealong-1.qmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---
title: Modules for LEGO attribute selections
format:
html:
code-line-numbers: false
---

As you make the transition to building production Shiny applications, Shiny modules are a very important tool to improve code organization and overall flow of your application. We will work together to build Shiny modules that let the user filter the underlying LEGO metadata based on a key variables in the overall data.
Expand Down Expand Up @@ -50,10 +53,74 @@ themes <- readRDS("../../data_examples/df_themes.rds")
dplyr::glimpse(themes)
```


## Plan

1. Create a new module R script (and possible a supporting R script) by using `golem::add_module()` in the `dev/02_dev.R` script.
1. Pick a Shiny input type that matches our requirements.
1. Ensure the server-side portion of the module returns the result of the selection, with additional post-processing if necessary.
1. Plug in the UI and server-side portions of the module in the main `app_ui.R` and `app_server.R` files, respectively.
1. Plug in the UI and server-side portions of the module in the main `app_ui.R` and `app_server.R` files, respectively.

## Solution (Theme Picker)

Create the module file with the following snippet:

```{r}
#| echo: true
#| eval: false
golem::add_module(name = "theme_picker", with_test = FALSE)
```

While we could choose a `selectInput` that displays the name of the theme as the choices and allow multiple to be selected, we want to incorporate a search box with snappy performance. The [`virtualSelectInput`](https://dreamrs.github.io/shinyWidgets/reference/virtualSelectInput.html) from the [`{shinyWidgets}`](https://dreamrs.github.io/shinyWidgets/index.html) package is an excellent solution.

Since we have the `themes` data set available, we can also leverage the supporting function `shinyWidgets::prepare_choices()` to get the possible choices ready for the input. The module will simply return the selection as a reactive variable.

```{r}
#| echo: true
#| eval: false
# UI portion
mod_theme_picker_ui <- function(id, label = NULL) {
ns <- NS(id)
themes <- dplyr::arrange(themes, name)
choices_list <- shinyWidgets::prepare_choices(
themes,
label = name,
value = theme_id
)
tagList(
virtualSelectInput(
ns("virt_theme_id"),
label = label,
choices = choices_list,
selected = themes$theme_id,
multiple = TRUE,
search = TRUE
)
)
}
# server portion
mod_theme_picker_server <- function(id){
moduleServer( id, function(input, output, session){
ns <- session$ns
return(reactive(input$virt_theme_id))
})
}
```

At the bottom of the module script, `{golem}` automatically includes commented code for referencing the module UI and server blocks in your main Shiny application. We can copy them into the `app_ui.R` and `app_server.R` files.

```{r}
#| echo: true
#| eval: false
# app_ui.R
mod_theme_picker_ui("theme_picker_1")
# app_server.R
input_theme_ids <- mod_theme_picker_server("theme_picker_1")
```

0 comments on commit c692672

Please sign in to comment.