I have a Shiny
app where n
pickerInputs
are generated by the user. If the user first generates the Inputs
and then makes the Choices
, it works fine. However, if the user generates an Input
, makes a Choice
and then decides to generate another Input
, the Choices
are restored.
One workaround for this is to extend the function generate_pickers_fun
with selected
. When there is a change in Picker selection
the function gets the Selections
when creating the picker. I have posted this as an solution.
The issue is though that everytime one new Picker
is selected to be generated, all the previous Pickers
are reran. Is there a solution to only update instead of rerunning?
library(shiny)
library(shinyWidgets)
library(tidyverse)
generate_pickers_fun <- function(picker_name, id){
picker <- pickerInput(
inputId = NS(id, picker_name),
label = picker_name,
multiple = TRUE,
choices = LETTERS[1:5]
)
return(picker)
}
ui_mod <- function(id) {
ns <- NS(id)
tagList(
pickerInput(NS(id, "generate_pickers"), choices = c("Picker_1", "Picker_2", "Picker_3", "Picker_4"), multiple = TRUE),
uiOutput(NS(id, "new_pickers"))
)
}
server_mod <- function(id) {
moduleServer(id, function(input, output, session) {
reactive_values <- reactiveValues()
observeEvent(input$generate_pickers, {
req(input$generate_pickers)
new_pickers <- map(input$generate_pickers, generate_pickers_fun, id = id)
output$new_pickers <- renderUI(tagList(new_pickers))
}, ignoreNULL = FALSE)
})
}
app <- function() {
ui <- fluidPage(
ui_mod("test")
)
server <- function(input, output, session) {
server_mod("test")
}
shinyApp(ui, server)
}
app()
You could rely on conditionalPanel
s instead of renderUI
and only show / hide the pickerInput
s when needed - so each input is rendered only once:
library(shiny)
library(shinyWidgets)
library(tidyverse)
generate_pickers_fun <- function(picker_name, id){
ns <- NS(id)
conditionalPanel(sprintf("input['generate_pickers'].includes('%s')", picker_name),
pickerInput(
inputId = ns(picker_name),
label = picker_name,
multiple = TRUE,
choices = LETTERS[1:5]
), ns = ns)
}
ui_mod <- function(id) {
ns <- NS(id)
picker_ids <- c("Picker_1", "Picker_2", "Picker_3", "Picker_4")
tagList(
pickerInput(NS(id, "generate_pickers"), choices = picker_ids, multiple = TRUE),
map(picker_ids, generate_pickers_fun, id = id)
)
}
server_mod <- function(id) {
moduleServer(id, function(input, output, session) {})
}
app <- function() {
ui <- fluidPage(
ui_mod("test")
)
server <- function(input, output, session) {
server_mod("test")
}
shinyApp(ui, server)
}
app()