Using selectinput on a named list to filter secondary selectinput

Hi all,

I'm currently working on a shiny app that requires somewhat dynamic inputs. Ideally, I want a situation where, using the list in the shiny app below, the user first selects a game (Mario, Zelda, or Starfox) using a selectInput(), once selecting the game they can complete another selectInput() on individuals from that specific game (had they chosen Mario, there is now a selectInput() including Mario, Peach, Luigi, and Bowser).

To better illustrate what I want I adapted the code below from here. However the difference I want is instead of one selectInput() that includes all character options I want two one for games, one for characters. The amount of character and games that the shiny app will actually require will be far too much for a single select input to handle gracefully.

shinyApp(
    ui = fluidPage(
        selectInput("game", "Choose a character:",
                    list(Mario = c("Mario", "Peach", "Luigi", "Bowser"),
                         `Legend of Zelda` = c("Link","Zelda", "Ganondorf", "Navi"),
                         Starfox = c("Fox", "Falco", "Wolf", "Slippi"))),
        textOutput("result")
    ),
    server = function(input, output) {
        output$result <- renderText({
            paste("You chose", input$game)
        })
    }
)

I'm sorry if this question has already been asked, the way I worded it did not return any similar questions.

Best regards,
Tim N

You can use updateSelectInput to achieve what you want

shinyApp(
    ui = fluidPage(
        selectInput("game", "Choose a game:", c("Mario", "Legend of Zelda", "Starfox")),
        selectInput("character", "Choose a character", choices = NULL), 
        textOutput("result")
    ),
    server = function(input, output, session) {
        output$result <- renderText({
            paste("You chose", paste(input$game,input$character, sep = ":"))
        })
        
        observeEvent(input$game, {
            game <- input$game
            if (game == "Mario") {
                characters <- c("Mario", "Peach", "Luigi", "Bowser")
            } else if (game == "Legend of Zelda") {
                characters <- c("Link","Zelda", "Ganondorf", "Navi")
            } else if (game == "Starfox") {
                characters <- c("Fox", "Falco", "Wolf", "Slippi")
            }
            updateSelectInput(session, "character", "Choose a character", characters)
        })
    }
)
1 Like

Awesome, thank you! I made some changes since I'm dealing with larger data structures, so for me it'll end up looking as follows, but I couldn't have done it without you.

library(shiny)
game_char_list <- list(Mario = c("Mario", "Peach", "Luigi", "Bowser"),
             `Legend of Zelda` = c("Link","Zelda", "Ganondorf", "Navi"),
             Starfox = c("Fox", "Falco", "Wolf", "Slippi"))
shinyApp(
    ui = fluidPage(
        selectInput("game", "Choose a game:", names(game_char_list)),
        selectInput("character", "Choose a character", choices = NULL), 
        textOutput("result")
    ),
    server = function(input, output, session) {
        output$result <- renderText({
            paste("You chose", paste(input$game,input$character, sep = ":"))
        })
        
        observeEvent(input$game, {
            game <- input$game
            characters <- game_char_list[[game]]
            updateSelectInput(session, "character", "Choose a character", characters)
        })
    }
)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.