I'm building a small UI where a user will enter into a splitLayout row of text that builds a statement (not needed for this question) to solve a puzzle.
However, if the user decides he/she needs an additional row or less rows to solve the puzzle I'd like adding or removing a new row of inputs to NOT delete the remaining input rows.
* the gray is a placeholder.
How can I best achieve my desired result of:
Please find my trimmed code below. Thanks for your input.
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("Identify A, B and C"),
sidebarLayout(
sidebarPanel(width = 5,
helpText("Present a statement and receive a response: 1 is a Knight who always tells the truth, 2 is a Knave who always lies, and 3 is a Normal who can do either."),
# Number of Questions
numericInput(inputId = "Questions", label = "Number of Questions",
value = 1, min = 1, max = 10, step = 1),
splitLayout(cellWidths = c("25%","70%"),
style = "border: 1px solid silver;",
cellArgs = list(style = "padding: 3px"),
uiOutput("textQuestions"), uiOutput("textQuestions2"))
),
mainPanel(
# Right hand side output
)
)
)
# Define server logic
server <- function(input, output) {
####### I don't want these to delete initially everytime??
output$textQuestions <- renderUI({
Questions <- as.integer(input$Questions)
lapply(1:Questions, function(i) {
textInput(inputId = paste0("Who", i), label = paste0(i, ". Ask:"), placeholder = "A")
})
})
########
output$textQuestions2 <- renderUI({
Questions <- as.integer(input$Questions)
lapply(1:Questions, function(i) {
textInput(inputId = paste0("Q", i) , label = paste0("Logic:"),
value = "", placeholder = "A == 1 & (B != 2 | C == 3)")
})
})
######
}
# Run the application
shinyApp(ui = ui, server = server)
It looks like someone already gave you an answer using uiOutput
+renderUI
, so I'm going to go the other route: using insertUI
and removeUI
.
Instead of having a numeric input for "number of questions", I replaced it with a button for "add question" and one for "remove question". I have a variable keeping track of how many questions there are. Every time "add question" is pressed, we add one row. When "remove question" is pressed, we remove the last row.
Here's the code:
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("Identify A, B and C"),
sidebarLayout(
sidebarPanel(
width = 5,
helpText("Present a statement and receive a response: 1 is a Knight who always tells the truth, 2 is a Knave who always lies, and 3 is a Normal who can do either."),
# Buttons to add/remove a question
actionButton("add", "Add question"),
actionButton("remove", "Remove question"),
div(id = "questions",
style = "border: 1px solid silver;")
),
mainPanel(
# Right hand side output
)
)
)
# Define server logic
server <- function(input, output) {
# Keep track of the number of questions
values <- reactiveValues(num_questions = 0)
# Add a question
observeEvent(input$add, ignoreNULL = FALSE, {
values$num_questions <- values$num_questions + 1
num <- values$num_questions
insertUI(
selector = "#questions", where = "beforeEnd",
splitLayout(
cellWidths = c("25%","70%"),
cellArgs = list(style = "padding: 3px"),
id = paste0("question", num),
textInput(inputId = paste0("Who", num),
label = paste0(num, ". Ask:"),
placeholder = "A"),
textInput(inputId = paste0("Q", num) ,
label = paste0("Logic:"),
placeholder = "A == 1 & (B != 2 | C == 3)")
)
)
})
# Remove a question
observeEvent(input$remove, {
num <- values$num_questions
# Don't let the user remove the very first question
if (num == 1) {
return()
}
removeUI(selector = paste0("#question", num))
values$num_questions <- values$num_questions - 1
})
}
# Run the application
shinyApp(ui = ui, server = server)
EDIT
OP requested a way to retrieve the user's input based on a question number. To do that:
Add the following to the UI
numericInput("question_num", "Show question number", 1),
textOutput("question")
Add the following to the server
get_question <- function(q) {
paste(
input[[paste0("Who", q)]],
":",
input[[paste0("Q", q)]]
)
}
output$question <- renderText({
get_question(input$question_num)
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With