R Shiny - add tabPanel to tabsetPanel dynamically (with the use of renderUI)

Here you go. The code is fairly self explanatory.

library(shiny)
runApp(list(
  ui = pageWithSidebar(
    headerPanel('Dynamic Tabs'),
    sidebarPanel(
      numericInput("nTabs", 'No. of Tabs', 5)
    ),
    mainPanel(
      uiOutput('mytabs')  
    )
  ),
  server = function(input, output, session){
    output$mytabs = renderUI({
      nTabs = input$nTabs
      myTabs = lapply(paste('Tab', 1: nTabs), tabPanel)
      do.call(tabsetPanel, myTabs)
    })
  }
))

There is a way to dynamically add tabPanels without renderUI, which might not be as obvious as the version with renderUI. I wrote a function addTabToTabset which will append any (list of) tabPanel(s) to a tabset/navbar.

This approach has a set of advantages over using renderUI:

  • Existing tabPanels are not re-rendered each time a new panel is added. (faster)
  • Thus, not resetting all the input variables inside existing Panels. (no variable storing workarounds needed)
  • Structure of the panel contents can be chosen individually. (In the lapply - renderUI version, all panels have to be somewhat uniform.)

The solution and code sample can be found in the answer here. If requested, I could also post the code here.