Colton
Colton

Reputation: 1297

How to get user input from an output object

I am creating a shiny app that dynamically creates a set of input boxes, the input from those boxes is then used to further create another set of input boxes.

First I get input from the "number of questions" text box and dynamically add that number of "question panels" to the ui (example below). enter image description here

Issue

The issue is that the generated objects are always attached to the output, and I can't figure out how to grab new user input from them. How could I get this input, and then generate a second round of "answer" input boxes?

ui.R

shinyUI(fluidPage(
  titlePanel("RSurvey"),
  numericInput("questionCountText", label = h3("Number of Questions"), value = 1),
  uiOutput("questionSet")
))

server.R

shinyServer(
  function(input, output) {    
      output[['questionSet']] <- renderUI({    
        
          outputHtml = ""
          count = input$questionCountText
          if(count > 0) {
            for(i in 1:input$questionCountText) {
              outputHtml = paste0(outputHtml, questionPanel(i))
            }
          }
          HTML(outputHtml)
      })        
  }
)

questionPanel = function(i)
{
  return(wellPanel(div(style="display:inline-block", textInput("questionText", label = h4(paste0("Question ", i)), "Enter your question")),
                                  numericInput1("answerCountText", label = h4("Number of Answers"), value = 3, onchange="onTextChanged(this.value)")))

}

numericInput1 = function (inputId, label, value = "", ...) 
{
  div(style="display:inline-block",
      tags$label(label, `for` = inputId), 
      tags$input(id = inputId, type = "numeric", value = value, ...))
}

Upvotes: 0

Views: 489

Answers (1)

Victorp
Victorp

Reputation: 13866

Hello try this for example :

#ui

ui <- fluidPage(
  titlePanel("RSurvey"),
  numericInput("questionCountText", label = h3("Number of Questions"), value = 1),
  uiOutput("questionSet"),
  verbatimTextOutput(outputId = "answers")
)

#server

server <- function(input, output) {
  output[['questionSet']] <- renderUI({    

    outputHtml = ""
    count = input$questionCountText
    if(count > 0) {
      for(i in 1:input$questionCountText) {
        outputHtml = paste0(outputHtml, questionPanel(i))
      }
    }
    HTML(outputHtml)
  })

  output$answers <- renderPrint({
    invisible(
      sapply(
        X = seq_len(input$questionCountText),
        FUN = function(i) {
          cat(paste0("Question", i, "\n", input[[paste0("questionText", i)]], "\n", input[[paste0("answerCountText", i)]], "\n"))
        }
      )
    )
  })
}

#app

shinyApp(ui = ui, server = server)

#utils

questionPanel = function(i) {
  wellPanel(
    div(
      style="display:inline-block",
      textInput2(inputId = paste0("questionText", i), label = h4(paste0("Question ", i)), placeholder = "Enter your question")
    ),
    numericInput1(inputId = paste0("answerCountText", i), label = h4("Number of Answers"), value = 3, onchange="onTextChanged(this.value)")
  )

}

numericInput1 = function (inputId, label, value = "", ...) {
  div(style="display:inline-block", class = "form-group shiny-input-container",
      tags$label(label, `for` = inputId), 
      tags$input(id = inputId, type = "number", value = value, ...))
}
`%AND%` <- shiny:::`%AND%`
textInput2 <- function (inputId, label, value = "", placeholder = NULL, width = NULL)
{
  if (is.null(placeholder)) {
    div(class = "form-group shiny-input-container", style = if (!is.null(width)) 
      paste0("width: ", validateCssUnit(width), ";"), label %AND% 
        tags$label(label, `for` = inputId), tags$input(id = inputId, 
                                                       type = "text", class = "form-control", value = value))
  } else {
    div(class = "form-group shiny-input-container", style = if (!is.null(width)) 
      paste0("width: ", validateCssUnit(width), ";"), label %AND% 
        tags$label(label, `for` = inputId), tags$input(id = inputId, placeholder = placeholder,
                                                       type = "text", class = "form-control", value = value))
  }

Upvotes: 1

Related Questions