I have a sidebarLayout
app in which I've set up buttons to add and remove tabPanel
s in the sidebarPanel
. However, I can't figure out how to customize those tabPanels. My code is below:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(width = 3, fixed=T,
h3("L2 Machine"),
actionButton('moreL2', tags$b('Add L2')),
actionButton('lessL2', tags$b('Remove L2')),
uiOutput('panelset'),
tabPanel("L2panel",
numericInput(inputId='L2amount', 'Select L2 Amount', value=0),
selectInput(inputId='L2type', 'Select L2 Type', c('Percent', 'Absolute')),
uiOutput('L2daterange')
)
),
mainPanel(
verbatimTextOutput('L2a'),
verbatimTextOutput('L2t')
)
)
)
server <- function(input, output) {
output$L2a <- renderPrint(input$L2amount)
output$L2t <- renderPrint(input$L2type)
output$panelset <- renderUI({
n <- seq(max(input$moreL2 - input$lessL2 + 1, 1))
tabList <- lapply(paste("Pan", n), tabPanel)
do.call(tabsetPanel, tabList)
})
output$L2daterange <- renderUI({
dateRangeInput(inputId='L2daterange',
label='Select Adjustment Period',
start='01-01-2010', end='01-12-2015'
)
})
}
shinyApp(ui, server)
Currently, I have numericInput()
, selectInput()
, and uiOutput()
inside tabPanel()
. Instead I want each tabPanel
created by clicking the button "Add L2" to have it's own set of numericInput
, selectInput
and uiOutput
.
You create indeed different tabPanels but they are empty - both numericInput
and selectInput
are not inside of dynamic tabPanels. The solution is based on https://gist.github.com/wch/5436415/ and you can find there an extensive explanation why do you need a function local
to render outputs with a for loop.
As said above, you created correctly dynamic tabPanels but they are empty. Within lapply
you should specify unique widgets as arguments to tabPanel
.
output$panelset <- renderUI({
n <- seq(max(input$moreL2 - input$lessL2 + 1, 1))
tabList <- lapply(paste("Pan", n), tabPanel)
do.call(tabsetPanel, tabList)
})
Here I coded an example of how you can do it the correct way. Each time you create a unique tabPanel with a unique set of widgets.
tabList <- lapply(n, function(i) {
tabPanel(
title = paste0('Pan', i),
numericInput(inputId = paste0('L2amount', i), 'Select L2 Amount', value = 0),
selectInput(inputId = paste0('L2type', i), 'Select L2 Type', c('Percent', 'Absolute')),
dateRangeInput(inputId = paste0('L2daterange',i),
label = 'Select Adjustment Period',
start = '01-01-2010', end = '01-12-2015'))
})
do.call(tabsetPanel, tabList)
})
Then for each tabPanel with unique set of widgets you have to create unique set of outputs and then you can render values of your widgets.
Full solution:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(width = 3, fixed=T,
h3("L2 Machine"),
actionButton('moreL2', tags$b('Add L2')),
actionButton('lessL2', tags$b('Remove L2')),
uiOutput('panelset')
),
mainPanel(
uiOutput("dynamic")
)
)
)
TMAX <- 10 # specify maximal number of dynamic panels
server <- function(input, output) {
output$panelset <- renderUI({
n <- seq(max(input$moreL2 - input$lessL2 + 1, 1))
# You have to create each time a new set of unique widgets
tabList <- lapply(n, function(i) {
tabPanel(
title = paste0('Pan', i),
numericInput(inputId = paste0('L2amount', i), 'Select L2 Amount', value = 0),
selectInput(inputId = paste0('L2type', i), 'Select L2 Type', c('Percent', 'Absolute')),
dateRangeInput(inputId = paste0('L2daterange',i),
label = 'Select Adjustment Period',
start = '01-01-2010', end = '01-12-2015'))
})
do.call(tabsetPanel, tabList)
})
output$dynamic <- renderUI({
n <- seq(max(input$moreL2 - input$lessL2 + 1, 1))
# You want to render n-times different outputs and each time you have
# k different outputs -- > need a list within a list.
lapply(n, function(i) {
list(
h5(paste0("Pan", i, " widgets")),
verbatimTextOutput(paste0('L2a', i)),
verbatimTextOutput(paste0('L2t', i)),
verbatimTextOutput(paste0('L2dat', i)),
br()
)
})
})
for (i in 1:TMAX) {
local({
my_i <- i
# Outputs
L2a <- paste0('L2a', my_i)
L2t <- paste0('L2t', my_i)
L2dat <- paste0('L2dat', my_i)
list(
output[[L2a]] <- renderPrint({ input[[paste0('L2amount', my_i)]] }),
output[[L2t]] <- renderPrint({ input[[paste0('L2type', my_i)]] }),
output[[L2dat]] <- renderPrint({ input[[paste0('L2daterange', my_i)]] })
)
})
}
}
shinyApp(ui, server)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.