Search code examples
rshinytextinputselectinput

r Shiny make textInput conditional on a previous selectInput


Hello and sorry for what might be a basic Shiny question.

In my mini-Shiny app, I want the user to:

  1. Pick a name from a list of pre-existing names using selectInput().

  2. Only if the name s/he has in mind is not on the list, I'd like a new widget to appear where s/he should enter the name using textInput().

I am stuck - my verbatimTextOutput statements inside the mainPanel on the UI side are not working.

Thank you for your hints!

library(shiny)

ui = shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      uiOutput("chosen_name", label = h4("Select one of the names:"))
    ),
    mainPanel(                       # Just shows what was selected
      # Next two lines don't work if uncommented:
      #  verbatimTextOutput('chosen_name')
      #  verbatimTextOutput("name_openend")
    )
  )
))

server = shinyServer(function(input, output, session) {

  # A vector of pre-existing names:
  mynames <- c("John", "Mary", "Jim")

  # Allow to select a name from the list of pre-existing names:
  output$chosen_name <- renderUI({
    selectInput('chosen_name',"Select a name:",
                choices = c("Name not on our list", mynames),
                selected = "Name not on our list")
  })

  # Open end box to enter name - if the name the user wants to enter is not on the list:
  output$name_openend <- renderUI({
    if (!output$chosen_name == 'Name not on our list') return(NULL) else {
      textInput("If the name you want is not on our list, type it here:")
    }
  })

})


shinyApp(ui = ui, server = server)

Solution

  • Updated Code

    library(shiny)
    
    ui = shinyUI(fluidPage(
    
      sidebarLayout(
        sidebarPanel(
          selectInput("chosen_name", "select name", choices = ""),
          uiOutput("new")
        ),
        mainPanel(
          textOutput("chosen")
        )
      )
    ))
    
    server = shinyServer(function(input, output, session) {
    
      # A vector of pre-existing names:
      mynames <- c("John", "Mary", "Jim")
    
      observe({
        updateSelectInput(session, inputId = "chosen_name", label = "Select a name:", choices = c(mynames, "Name not on our list"))
      })
    
      # Open end box to enter name - if the name the user wants to enter is not on the list:
      output$new <- renderUI({
        if (!input$chosen_name == 'Name not on our list') return(NULL) else {
          textInput("Not_on_list", "If the name you want is not on our list, type it here:")
        }
      })
      #
      # 
      # Allow to select a name from the list of pre-existing names:
    
      output$chosen <- renderText({
        if (!input$chosen_name == 'Name not on our list') {
        return(paste("Chosen name:", input$chosen_name))
        }
        else {
          return(paste("Chosen name:", input$Not_on_list))
        }
      })
    
    })
    
    shinyApp(ui = ui, server = server)