0

I want to have a UI which allows a user to give certain inputs, and if he requires more inputs he shall be able to click a button which then opens up new inputs. This has worked out fine thanks to this entry.

However, now I want to create a dataframe out of these inputs and I am struggling with that. This is my code:

library(shiny)

ui <- fluidPage(
 
  fluidRow(
    column(
      width = 6,
      uiOutput("selection_ui")
    ),
      
    column(
      width = 3,
      uiOutput("amount_ui")
    ),
    
    column(
      width = 3,
      uiOutput("year_ui")
    )
  ),
  
  fluidRow(
    column(
      width = 6,
      actionButton(inputId = "addEntry", 
                   label = "Add Entry")
    ),
    
    column(
      width = 6,
      actionButton(inputId = "deleteEntry",
                   label = "Delete Entry")
    )
  ),
  br(),
  
  fluidRow(
    column(
      width = 12,
      actionButton(inputId = "Go",
                   label = "Submit")
    )
  ),
  
  dataTableOutput("Dataframe")
)

server <- function(input, output){
  
  counter <- reactiveValues(value = 1)
  
  AllInputs <- reactive({
    x <- reactiveValuesToList(input)
  })
  
  observeEvent(input$addEntry, {
    counter$value <- counter$value + 1
  })
  
  observeEvent(input$deleteEntry, {
    req( counter$value >= 2 )
    counter$value <- counter$value - 1
  })
  
  selection <- reactive({
    n <- counter$value
    
    if(n > 0){
      isolate({
        lapply(seq_len(n), function(i){
          selectInput( inputId = paste0("select",i),
                       label = paste0(i, "-th selection:"),
                       choices = as.list(c("", "A", "B", "C")),
                       selected = AllInputs()[[paste0("select",i)]]
          )
        })
      })
    }
  })
  
  amount <- reactive({
    n <- counter$value
    
    if(n > 0){
      isolate({
        lapply(seq_len(n), function(i){
          numericInput(inputId = paste0("number",i),
                       label = paste0(i, "-th amount:"),
                       value = AllInputs()[[paste0("number",i)]])
        })
      })
    }
  })
  
  year <- reactive({
    n <- counter$value
    
    if(n > 0){
      isolate({
        lapply(seq_len(n), function(i){
          numericInput(inputId = paste0("year",i),
                       label = paste0(i, "-th year:"),
                       value = AllInputs()[[paste0("year",i)]])
        })
      })
    }
  })
  
  output$selection_ui <- renderUI({selection()})
  output$amount_ui <- renderUI({amount()})
  output$year_ui <- renderUI({year()})

  eventReactive(input$Go, {
    df <- data.frame(CREATE DATAFRAME HERE)
  })
  
  output$dataframe <- renderDataTable(df())
}

shinyApp(ui = ui, server = server)
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61

1 Answers1

0

I think I solved it using sapply():

  df <- eventReactive(input$Go, {
    n <- counter$value

    tmp1 <- sapply(seq_len(n), function(i){
      input[[paste0("select",i)]]
    })
    
    tmp2 <- sapply(seq_len(n), function(i){
      input[[paste0("number",i)]]
    })
    
    tmp3 <- sapply(seq_len(n), function(i){
      input[[paste0("year",i)]]
    })
    
    data.frame(col1 = tmp1, 
               col2 = tmp2,
               col3 = tmp3 
              )
  })