My app contains two tabSetPanel that are created based on user input (in the example below the user input is a group of radio buttons). The user input determines both the number of tabs in both tabSetPanels AND the selected tab. I also want the two tabSetPanels to display the same tab whenever user input is changed or different tab is selected in either sets. The original app contains feature that prevents me from merging the two tabSetPanels. The problem is that both tabSetPanels initially display tabs without any content. Here is a minimal reproducible example:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
# User input for number of tabs and selected tab
radioButtons("tabSelector", "Select Number of Tabs", 1:3, 1),
br()
),
mainPanel(
uiOutput(
"set1"
),
uiOutput(
"set2"
)
)
)
)
server <- function(input, output, sesstion){
output$set1 <- renderUI({
tabs <- list()
for(i in seq_len(input$tabSelector)){
tabs[[i]] <- tabPanel(
title = paste0("tab",i),
value = i,
numericInput(
paste0("num",i),
"Number",
value = 0
)
)
}
do.call(tabsetPanel, c(tabs,
list(id = "set1",
selected = input$tabSelector)))
})
output$set2 <- renderUI({
tabs <- list()
for(i in seq_len(input$tabSelector)){
tabs[[i]] <- tabPanel(
title = paste0("tab",i),
value = i,
numericInput(
paste0("num",i),
"Number",
value = 0
)
)
}
do.call(tabsetPanel, c(tabs,
list(id = "set2",
selected = input$tabSelector)))
})
# Bind the two tabSetPanels
observeEvent(input$set1, {
updateTabsetPanel(inputId = "set2", selected = input$set1)
})
observeEvent(input$set2,{
updateTabsetPanel(inputId = "set1", selected = input$set2)
})
} # end server function
if (interactive()) {
shinyApp(ui, server)
}
Thanks in advance
CodePudding user response:
The value of a
tabPanel
must be a character string :output$set1 <- renderUI({ tabs <- list() for(i in seq_len(input$tabSelector)){ tabs[[i]] <- tabPanel( title = paste0("tab",i), value = as.character(i), numericInput( paste0("num",i), "Number", value = 0 ) ) } do.call(tabsetPanel, c(tabs, list(id = "set1", selected = as.character(input$tabSelector)) )) })
In
output$set2
you don't need to set the value of theselected
argument, because it will be set by theupdateTabsetPanel
.Duplicated ids are not allowed in HTML, so you have to change the id
paste0("num",i)
of your numeric inputs to something else in one of the two tabsets.