I made a very simple Shiny app that has just two dropdown inputs. The second input is dependent on the first. The last thing I would like to add is a loading spinner for the second dropdown input vars_subspecies
.
I was able to achieve this spinner using spsComps::addLoader
without using modularity but it's not working when I use modules.
Here is a fully working example:
### global.R
library(shiny)
library(dplyr)
source("tab1_ui.R", local = T)
source("tab1_server.R", local = T)
# Create sub_species column
iris2 <- iris %>%
mutate(
subspecies = case_when(
startsWith(as.character(Species), "setosa") ~ rep(c("setosa1", "setosa2"), length.out = n()),
startsWith(as.character(Species), "versicolor") ~ rep(c("versicolor1", "versicolor2"), length.out = n()),
startsWith(as.character(Species), "virginica") ~ rep(c("virginica1", "virginica2"), length.out = n())
)
)
### ui.R
fluidPage(
sidebarLayout(
sidebarPanel(
dropdownsUI("dropdowns")
),
mainPanel(
)
)
)
### server.R
function(input, output, session) {
subspeciesServer("dropdowns")
}
### tab1_ui.R
dropdownsUI <- function(id) {
ns <- NS(id)
tagList(
selectInput(ns("speciesDropdown"), label = "Species:", choices = c("setosa", "versicolor", "virginica")),
div(
id = "subspecies_container",
uiOutput(ns("subspeciesDropdown"))
)
)
}
### tab1_server.R
subspeciesServer <- function(id) {
moduleServer(id, function(input, output, session) {
dependent_subspecies <- reactive({
iris2 %>%
filter(Species == req(input$speciesDropdown)) %>%
pull(subspecies) %>%
unique()
})
subspecies_loader <- spsComps::addLoader$new(target_selector = "subspecies_container")
output$subspeciesDropdown <- renderUI({
subspecies_loader$show()
on.exit({subspecies_loader$hide()})
Sys.sleep(1)
selectInput("vars_subspecies", "Sub Species:", choices = dependent_subspecies())
})
}
)
}
CodePudding user response:
Because you are missing a ns
in your UI:
div(
id = ns("subspecies_container"),
uiOutput(ns("subspeciesDropdown"))
)
Remember in all module elements, anytime you use ID, ns
is required.