Get tab titles from all tabPanels in a tabsetPanel

shiny
rstudio

#1

Hi,

Is it possible from a Shiny app to get the titles or ids of the child tabPanels in a tabsetPanel? I create a number of tabPanels in a tabsetPanel, and dependent on user choises the title of the panels change. I would like to iterate over the tabPanels and use the title. There are of course other ways of accomplishing what I want without iterating over the tabPanels, but I just couldn't find this answer anywhere?

Cheers
Steen


#2

You can get the tabPanel titles via Javascript. Here's a simple example.

library(shiny)
ui <- fluidPage(
  tags$script(type="text/javascript", src = "tabinfo.js"),
  titlePanel(div("Tab names")),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      tabsetPanel(type = "tab", id= "tabPanel1",
                  tabPanel("TabName1", p(), textOutput("names")),
                  tabPanel("TabName2")
      )
    )
  )
)

server <- function(input, output) {
  output$names <- renderText({
    input$tabNames
  })
}
shinyApp(ui = ui, server = server)

tabinfo.js:
$(document).on("shiny:connected", function(e) {
    tabNames = []
    var links = document.getElementsByTagName("a");
    for (var i = 0, len = links.length; i < len; i++) {
        if (links[i].getAttribute("href").indexOf("#tab-") == 0) {
            tabNames.push(links[i].getAttribute("data-value"));
        }
    }
    Shiny.onInputChange("tabNames", tabNames);
});

#3

Thanks, ginberg, that looks great!

I guess this will not work if there are more than one tabsetPanel or navbarMenu on the page, and if there are tabsetPanels on "hidden" tabs, as this looks through all the <a> tags on the page, right? Each tabsetPanel has an id (four digit number), is there a way to limit your function to a tabsetPanel of a given id?

Cheers
Steen


#4

yes that's right, it just looks if the link belongs to a tab.
One thing what you could do, is pass the id of the tabsetPanel with the tabname and then filter in R based on this id.

$(document).on("shiny:connected", function(e) {
    tabNames = []
    var links = document.getElementsByTagName("a");
    for (var i = 0, len = links.length; i < len; i++) {
        link = links[i];
        if (link.getAttribute("href").indexOf("#tab-") == 0) {
            panelId = link.parentElement.parentElement.getAttribute("id");
            tabNames.push(panelId + "-" + link.getAttribute("data-value"));
        }
    }
    Shiny.onInputChange("tabNames", tabNames);
});