michaelmccarthy404
michaelmccarthy404

Reputation: 508

How to render a varying numbers of tables based on user input in R Shiny?

In an R shiny app I'm attempting to render a varying number of tables based on user input. As an example, I've created the following app:

# ui.R

fluidPage(
  numericInput("numeric.input", "Select Number of Tables:", 0, min = 0),
  tableOutput("table")
)

# server.R

data(iris)

function(input, output) {
  output$table <- renderTable({
    head(iris)
  })
}

What I'd like for this app to do is to generate a number of tables dependent on the value selected for numeric.input. Currently numeric.input doesn't influence the app and is only shown for example. If numeric.input is set to zero, I'd like for the app to display no copies of the table, if numeric.input is set to one, I'd like for the app to display one copy of the table, etc.

Is something like this possible in R Shiny?

Upvotes: 1

Views: 1078

Answers (2)

user5249203
user5249203

Reputation: 4638

Your approach is simple and straightforward. Just putting out the usage of the insertUI and removeUI for this purpose based on the link provided in comments by @r2evans.

ui <- fluidPage(
  numericInput("numericinput", "Select Number of Tables:", 0, min = 0),
  tags$div(id = 'tabledisplay')
)

server <- function(input, output) {
  inserted <- c()
  observeEvent(input$numericinput, {
    tablenum <- input$numericinput
    id <- paste0('table', tablenum)
    if (input$numericinput > length(inserted)) {
      insertUI(selector = '#tabledisplay',
               ui = tags$div(h4(
                 paste0("Table number ", input$numericinput)
               ), tags$p(renderTable({
                 head(iris)
               })),
               id = id))
      inserted <<- c(id, inserted)
    }
    else {
      inserted <- sort(inserted)
      removeUI(selector = paste0('#', inserted[length(inserted)]))          
      inserted <<- inserted[-length(inserted)]
    }
  })
}
shinyApp(ui, server)

Upvotes: 0

michaelmccarthy404
michaelmccarthy404

Reputation: 508

I've solved the issue by using the R Shiny Gallery app on creating UI in a loop, but rendering the UI loop within the R Shiny server. The following code works correctly:

# ui.R

fluidPage(
  numericInput("numeric.input", "Select Number of Tables:", 1, min = 1),
  uiOutput("tables")
)

# server.R

data(iris)

function(input, output) {

  # Rendering tables dependent on user input.
  observeEvent(input$numeric.input, {
    lapply(1:input$numeric.input, function(i) {
      output[[paste0('table', i)]] <- renderTable({
        head(iris)
      })
    })
  })

  # Rendering UI and outputtign tables dependent on user input.
  output$tables <- renderUI({
    lapply(1:input$numeric.input, function(i) {
      uiOutput(paste0('table', i))
    })
  })

}

Upvotes: 1

Related Questions