Create an arbitrary number of inputtext elements

Hi all.

I'm wondering if there's a way of creating an arbitrary number of textinput fields in shiny.

Right now I can see a way of creating a fixed number of textinput fields. (In the example below I made 3.)


library(shiny)

ui <- fluidPage(
    
    # Application title
    titlePanel("Get Names"),
    
    fluidRow(
        
        # new column so that the table doesn't take the full page
        column("",
               width = 10, offset = 1,
               tags$h3("Text Box Area"),
                
               panel(
                   textInput("name1", "Name 1"),
                   textInput("name2", "Name 2"),
                   textInput("name3", "Name 3"),
                   actionButton("getNames", "Use these names")
               ),
               
               tags$h3("Table Area"),
               
               # Show a table of the players
               dataTableOutput("table")
               
        )
    )
)

# Define server logic 
server <- function(input, output) {

    
    names_df <- eventReactive(input$getNames, {
        
        tibble(
            ID = 1:3,
            Name = c(input$name1, input$name2, input$name3)
        )
    })
    
    output$table <- renderDT({
        names_df()
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

But I'm wondering how it would work to read text boxes from a numeric source (slider maybe?), then have an action button to a user-specified number of textinput fields based on a the numeric source.

I have a guess for how it should maybe look, but I'm okay with being totally wrong / taking an entirely new approach.

library(shiny)

ui <- fluidPage(
    
    # Application title
    titlePanel("Get Names"),
    
    fluidRow(
        
        # new column
        column("",
               width = 10, offset = 1,
               tags$h3("Select Area"),
               
               # get player count 
               panel(
                   sliderInput("nNames", "Number of People", 5, 20, 9),
                   actionButton("getNamesNumber", "Set Number of People")
               ),
               
               # set player names
               panel(
                   
                   # I NEED HELP HERE 3rd
                   # i have no idea how i would get a multiple text box input 
                   # THANKS 
                   
                   actionButton("getNames", "Set Names")
               ),
               
               tags$h3("Table Area"),
               
               # Show a table of the players
               dataTableOutput("table")
               
        )
    )
)

# Define server logic 
server <- function(input, output) {

    
    build_text_fields <- eventReactive(input$nNames, {
        
        # I NEED HELP HERE 1ST
        # some sort of do.call command combined with inputtext
        # that also uses the nNames input above? I'm really lost
        # THANKS 
    })
    
    
    output$text_fields <- ### I NEED HELP HERE 2ND
        # I don't what sort of field this should be.
        # My best guess is 
        renderSomething({ build_text_fields() })
        # but i don't know what something i should render
        # THANKS
        
    
    names_df <- eventReactive(input$getNames, {
        
        tibble(
            ID = 1:input$nNames,
            Name = input$nameList
        )
    })
    
    
    output$table <- renderDT({
        names_df()
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

Thanks for looking at my weird request.


library(shiny)
library(shinyWidgets) # you chose to use panel()
library(DT) # you want to renderDT
library(purrr) # iteration
ui <- fluidPage(
  
  # Application title
  titlePanel("Get Names"),
  
  fluidRow(
    
    # new column so that the table doesn't take the full page
    column("",
           width = 10, offset = 1,
           tags$h3("Text Box Area"),
           
           panel(
           sliderInput("num_text_fields","How Many Text Fields ?",1,5,3),
           uiOutput("multi_text_fields"),
             actionButton("getNames", "Use these names")
           ),
           
           tags$h3("Table Area"),
           
           # Show a table of the players
           dataTableOutput("table")
           
    )
  )
)

# Define server logic 
server <- function(input, output) {
  
   dynamic_list_of_text_fields <- reactive ({
      ntf<- req(input$num_text_fields)
     purrr::map(1:ntf,
                ~textInput(paste0("name",.), paste("Name",.)))
   })
  output$multi_text_fields <- renderUI({
    div(
      req(dynamic_list_of_text_fields())
    )
  })

  names_df <- eventReactive(input$getNames, {
    ntf<-req(input$num_text_fields)
    tibble(
      ID = 1:ntf,
      Name = purrr::map(1:ntf,
                        ~input[[paste0("name",.)]])
    )
  })
  
  output$table <- renderDT({
    names_df()
  })
}

# Run the application 
shinyApp(ui = ui, server = server)
1 Like

What an elegant solution! Thank you so much!
I clearly have a lot to learn about the purrr package!

also, I forgot to load dplyr, so i'll make sure to include that too! :smiley:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.