Reputation: 117
I'm trying to come up with an app in Shiny that receives an initial inputs called "number of stakeholders", and depending on that number, I'd like it to change the amount of tabs in the navbarPage()
and navlistPanel()
structures.
The current code I have replicates a similar sequence as many times as the max number of fixed stakeholders I set, leaving me with a huge 10.000 lines code that repeats continuously commands as:
tabPanel("Stakeholder #3",
fluidRow(
column(2, textInput(inputId = "sh.name.3", label = "Stakeholder's name")),
column(1),
column(4, textInput(inputId = "sh.3.option.1", label = "Option #1")),
column(1),
column(4, textInput(inputId = "sh.3.option.2", label = "Option #2"))
),
fluidRow(
column(3),
column(4, textInput(inputId = "sh.3.option.3", label = "Option #3")),
column(1),
column(4, textInput(inputId = "sh.3.option.4", label = "Option #4"))
),
I'm trying to find an option that allows me to create a more compact code at the same time that provides me with a way of making a dynamic UI, which will imply the need of finding a way to be able to manage the variables dynamically as well.
Even though R naturally allows to manage variables in a very fluid way, I haven't been successful at using structures like lists, vectors or data frames in Shiny.
I checked for several days but I wasn't able to find something more elaborate than this (which has a problem with the variables resetting itself): http://shiny.rstudio.com/gallery/dynamic-ui.html
Is there any solution to perform something like what I am looking for?
Thank you in advanced.
Upvotes: 0
Views: 890
Reputation: 9676
Creating a dynamic set of Panels is fairly easy using lapply. Suppose your given number of stakeholders is n
, your code will be:
n = 10
app <- shinyApp(
ui = shinyUI(fluidPage(
uiOutput("tabsets")
)),
server = function(input, output, session){
output$tabsets <- renderUI({
Panels <- lapply(1:n, function(number){
tabPanel(paste0("Stakeholder #", number),
fluidRow(
column(2, textInput(inputId = paste0("sh.name.", number), label = "Stakeholder's name")),
column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.1"), label = "Option #1")),
column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.2"), label = "Option #2"))
),
fluidRow(
column(4, offset = 3, textInput(inputId = paste0("sh.", number, ".option.3"), label = "Option #3")),
column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.4"), label = "Option #4"))
)
)
})
do.call(tabsetPanel,Panels)
})
}
)
runApp(app)
I also changed your empty columns to be included in the offset
attribute of your non-empty columns.
Upvotes: 3