I am trying to build a Shiny interface with:
Here's a minimal reproducible example.
If "First" is chosen from the main selector, then a submenu with two possibilities [1,2] exist. These possibilities result in 1 or 2 subsequent inputs being built. So these possibilities:
If "Second" is chosen from the main selector, then a submenu with two possibilities [3,4] exist. These possibilities result in 3 or 4 subsequent inputs being built.
ui <- fluidPage(
radioButtons(inputId="main_selector",label=h5('Select menu'),
choices = list('First','Second'),selected='First'),
uiOutput("ui_selected")
)
server <- function(input, output, session) {
build_inputs <- function(choices){
output = tagList()
for(i in 1:choices){
output[[i]] = tagList()
output[[i]][[1]] = numericInput(inputId = paste0(i),
label = paste0(i),
value = i)
}
}
# Are these reactive elements necessary? Should they be in the renderUI below?
first_submenu <- reactive({
input$first_submenu
})
second_submenu <- reactive({
input$second_submenu
})
output$ui_selected <- renderUI({
if (input$main_selector == 'First'){
selectInput(inputId = "first_submenu", label="First submenu",
choices=list(1,2))
choices_1 <- first_submenu()
# Build a list of inputs dependent on the choice above
output <- build_inputs(choices_1)
} else if (input$main_selector == 'Second'){
selectInput(inputId = "second_submenu", label="Second submenu",
choices=list(3,4))
choices_2 <- second_submenu()
# Build a list of inputs dependent on the choice above
output <- build_inputs(choices_2)
# Return output as output$ui_selected element
output
})
}
shinyApp(ui, server)
The error I receive is Warning: Error in :: argument of length 0 . I believe this is because you can't call the outcome of first_submenu from the renderUI element - but I don't know how to structure my code correctly.
I am not sure whether this is what you are after. The main problem was that your function build_inputs
does not return anything. The second problem is that choices from selectInput
are not numeric, so you need to convert them beforehand. And one other minor problem, related to the error you mention, is that the elements you want to render exist at the same time, so putting a condition on input$first_submenu
will trigger errors (even if it is NULL
for a couple of milliseconds), so it's (almost always) good practice to take care of possibly null inputs. The last thing I did was to add another uiOutput
for the last layer of dynamic inputs. Hope this helps.
ui <- fluidPage(
radioButtons(inputId="main_selector",label=h5('Select menu'),
choices = list('First','Second'),selected='First'),
uiOutput("ui_selected"),
uiOutput("ui_numeric_inputs")
)
server <- function(input, output, session) {
build_inputs <- function(choices) {
output = tagList()
for(i in 1:choices){
output[[i]] = tagList()
output[[i]][[1]] = numericInput(inputId = paste0(i),
label = paste0(i),
value = i)
}
return(output)
}
output$ui_selected <- renderUI({
if (input$main_selector == 'First'){
selectInput(inputId = "first_submenu", label="First submenu",
choices=c(1,2))
} else if (input$main_selector == 'Second'){
selectInput(inputId = "second_submenu", label="Second submenu",
choices=list(3,4))
}
})
output$ui_numeric_inputs <- renderUI({
if (input$main_selector == 'First' &&
(!is.null(input$first_submenu))) {
build_inputs(as.numeric(input$first_submenu))
} else if (input$main_selector == 'Second' &&
(!is.null(input$second_submenu))){
build_inputs(as.numeric(input$second_submenu))
}
})
}
shinyApp(ui, server)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.