Skip to content

Instantly share code, notes, and snippets.

@wch
Last active January 21, 2022 14:25
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save wch/9609200 to your computer and use it in GitHub Desktop.
Save wch/9609200 to your computer and use it in GitHub Desktop.
Dynamic UI example app for R Shiny

The user interface components in this example are generated as HTML on the server inside a renderUI() block and sent to the client, which displays them with uiOutput(). Each time a new component is sent to the client, it completely replaces the previous component. This is different from the udpate input demo app, where the value of an existing input component is changed with a command from the server, but the component itself is not replaced with a new one.

Type: Shiny
Title: Dynamic UI
License: MIT
Author: Winston Chang <winston@rstudio.com>
AuthorUrl: http://www.rstudio.com/
Tags: dynamic-ui renderui uioutput
DisplayMode: Showcase
shinyServer(function(input, output) {
output$ui <- renderUI({
if (is.null(input$input_type))
return()
# Depending on input$input_type, we'll generate a different
# UI component and send it to the client.
switch(input$input_type,
"slider" = sliderInput("dynamic", "Dynamic",
min = 1, max = 20, value = 10),
"text" = textInput("dynamic", "Dynamic",
value = "starting value"),
"numeric" = numericInput("dynamic", "Dynamic",
value = 12),
"checkbox" = checkboxInput("dynamic", "Dynamic",
value = TRUE),
"checkboxGroup" = checkboxGroupInput("dynamic", "Dynamic",
choices = c("Option 1" = "option1",
"Option 2" = "option2"),
selected = "option2"
),
"radioButtons" = radioButtons("dynamic", "Dynamic",
choices = c("Option 1" = "option1",
"Option 2" = "option2"),
selected = "option2"
),
"selectInput" = selectInput("dynamic", "Dynamic",
choices = c("Option 1" = "option1",
"Option 2" = "option2"),
selected = "option2"
),
"selectInput (multi)" = selectInput("dynamic", "Dynamic",
choices = c("Option 1" = "option1",
"Option 2" = "option2"),
selected = c("option1", "option2"),
multiple = TRUE
),
"date" = dateInput("dynamic", "Dynamic"),
"daterange" = dateRangeInput("dynamic", "Dynamic")
)
})
output$input_type_text <- renderText({
input$input_type
})
output$dynamic_value <- renderPrint({
str(input$dynamic)
})
})
shinyUI(fluidPage(
titlePanel("Dynamically generated user interface components"),
fluidRow(
column(3, wellPanel(
selectInput("input_type", "Input type",
c("slider", "text", "numeric", "checkbox",
"checkboxGroup", "radioButtons", "selectInput",
"selectInput (multi)", "date", "daterange"
)
)
)),
column(3, wellPanel(
# This outputs the dynamic UI component
uiOutput("ui")
)),
column(3,
tags$p("Input type:"),
verbatimTextOutput("input_type_text"),
tags$p("Dynamic input value:"),
verbatimTextOutput("dynamic_value")
)
)
))
@ai2create
Copy link

Hi Winston,
Thanks for such a nice post. I am facing some issue in dynamic menu dropdown.
I am unable to view the list of file in the dropdown menu depending on the selection of directory form another menu dropdown. Please guide me.

TRY1:

================================

options(shiny.trace=TRUE)

ui <- fluidPage(
titlePanel("test"),
sidebarLayout(
sidebarPanel(selectInput("dir",
label = "dir_id",
choices = (as.list(substr(list.dirs(paste0("D:/BW/test")),start= 12,stop=15)))),

             conditionalPanel(condition = "output.file1 == true",                
             selectInput("file2",textOutput("text1"),choices =textOutput("text1") ))
  ),
   mainPanel(
  uiOutput("text1")
) ) )

server <- function(input, output) {
output$text1 <- renderText({
reactive({
files <- as.list(substr(list.files(paste0("D:/BW/test/",input$dir,"/")),start= 1, stop=1))})
if(is.null(file1)){return()}
observe({updateSelectInput("file1","choose file",choices = files)})
})}

shinyApp(ui,server)

TRY2:

================================

ui <- fluidPage(
titlePanel("test"),
sidebarLayout(
sidebarPanel(
wellPanel(selectInput("Country", "Select a Country:",
uiOutput('text1'))),
wellPanel(selectInput("State", "Select a State:",
uiOutput('text2')))),
mainPanel("")
)
)
server <- function(input, output) {

output$text1 <- renderUI({

observe({
updateSelectInput(session, "Country", choices = reactive({as.list(substr(list.dirs(paste0("D:/BW/test")),start= 12,stop=15))}))}) })

output$text2 <- renderUI({
observe({
files <- as.list(substr(list.files(paste0("D:/BW/test/",input$Country,"/")),start= 1, stop=1))
updateSelectInput(session, "State", choices = files) })
})

shinyApp(ui,server)

@NabeelahB
Copy link

Hi,
I am trying to do a similar thing. But instead of cascading dropdown lists, i want to update lists dynamically without a hierarchy.

I am having a little tricky situation. Similar to the above one, yet different.

I have a dataframe of 7 variables. Which can be filtered in 6 different ways.

I have 6 input lists(dropdown menu). By default all of them have a null value selected. When even 1 of the list value is selected then the other 5 lists should show values based on the first selection. if 2 lists are chosen then the options in the other lists will be based on these 2 values and so on.
There is no set priority of which input will be selected first. But whichever list is chosen, all the other lists should reflect values accordingly.

So if i take this sample dataframe
data = data.frame(Year=c("2002","2003","2004","2003","2001","2002", "2001"),
Month = c("Jan", "Feb", "Mar", "Jan", "Dec", "Jan", "Nov"),
Name =c("Sam", "Paul", "James", "Ana","Rose", "Juan", "Tim"),
row.names=NULL, stringsAsFactors = FALSE)
I can choose Month first and select "Jan" the available years should show 2002 & 2003. and the names Sam, Ana & Juan.

Help will be appreciated.

Regards,
Nabeelah

@dicook
Copy link

dicook commented Apr 12, 2018

Winston, Can the slider be made to update continuously? I particularly want to generate a manual controlled tour, and as I slide the slider I would like the plot to change incrementally.

The slider for the most part seems to only update once you lift up the mouse button.

It seems that if the slide is long enough it may update a couple of times while dragging it, but its not nearly smooth or frequent enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment