Reputation: 1948
Hello and sorry for what might be a basic Shiny question.
In my mini-Shiny app, I want the user to:
Pick a name from a list of pre-existing names using selectInput().
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)
Upvotes: 1
Views: 2520
Reputation: 422
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)
Upvotes: 1
Reputation: 17689
You confused a bit the functions on the ui side:
If you use renderUI()
on the server side, you will have to use uiOutput()
on the ui side to make it work. Also you should avoid using the same id twice. Finally, for the textinput i added an id and a label.
Full code reads:
library(shiny)
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput("chosen_nm", label = h4("Select one of the names:"))
),
mainPanel( # Just shows what was selected
# Next two lines don't work if uncommented:
uiOutput("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_nm <- renderUI({
selectInput('chosen_name',"Select a name:",
choices = c("Name not on our list", mynames),
selected = "Name not on our list")
})
output$chosen_name2 <- renderText({
paste("The chosen name is: ", input$chosen_name)
})
# Open end box to enter name - if the name the user wants to enter is not on the list:
output$name_openend <- renderUI({
req(input$chosen_name)
if (input$chosen_name == 'Name not on our list'){
textInput("newName", "If the name you want is not on our list, type it here:")
}else{
verbatimTextOutput('chosen_name2')
}
})
})
shinyApp(ui = ui, server = server)
Upvotes: 1
Reputation: 66
There were a few things that I needed to cut out to make it work. First was the sidebarLayout. This might have been messing with your mainPanel. I am sure you can get this to work just make sure the mainPanel is in the right place and not being added to the sidebarLayout, which might have been the problem.
There were a few other problems like renderUI and UIOutput. Maybe someone else will add a post on how to use those functions. Also, I added a reactive function so the textOutput would change.
Take a look at how mine works.
mynames <- c("John", "Mary", "Jim")
ui = shinyUI(
fluidPage(
sidebarPanel(
selectInput('chosen_name',"Select a name:",
choices = c("Name not on our list", mynames),
selected = "Name not on our list")
),
mainPanel(
textOutput('chosen_name2')
)
)
)
server = shinyServer(function(input, output, session) {
# A vector of pre-existing names:
selectedchosen_name <- reactive({
if (input$chosen_name == 'Name not on our list') {return("Pick a name")} else {
return("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_name2 <- renderText({
selectedchosen_name()
})
# Open end box to enter name - if the name the user wants to enter is not on the list:
})
shinyApp(ui = ui, server = server)
I removed some parts that might be redundant, but right now it's simplified so you can add to it. If you have any questions just ask.
Upvotes: 0