Search code examples
rshinynavbar

How can I get two navigation bar with shiny apps?


I am trying to get two navigation bars, specifically, all the tools like gene expressions, genomic, epigenetics to fall under the tools.

I have been following this link Shiny: Independently navigate two tabsetPanels but I haven't being able to solve it.

If I can keep the structure of the code app_ui the way it is and change it a bit, that will be nice. I believe if I keep it the way it is, this is elegant enough!

Here is the pic I have to show you clearly the output

enter image description here

Here is a snipped of the code:

    app_ui <- function(request) {
  tagList(
    # Leave this function for adding external resources
    golem_add_external_resources(),
    shinyjs::useShinyjs(),
    # Include shinyjs
    shiny::navbarPage(
      # # add PHS logo to navigation bar
      title = div(tags$a(
        img(src = "www/bftb_logo_v8_bare.png", height = "40px"),
        "AZ Oncology Bioinformatics Toolbox"
      )),

      # make navigation bar collapse on smaller screens
      windowTitle = "AstraZeneca Oncology profiles",
      collapsible = TRUE,

      header = tags$head(
        # sourcing css style sheet
        includeCSS("www/style.css"),

        # include scotpho icon in web browser
        HTML("<html lang='en'>"),
        tags$link(rel = "shortcut icon",
                  href = "bftb_logo_v8_bare.ico"),

        # include google analytics scripts
        # includeScript("google-analytics.js"), # GA 3
        # HTML('<script async src="https://www.googletagmanager.com/gtag/js?id=G-KE1C59RLNS"></script>'),
        # includeScript("gtag.js") # Google analytics 4

      ),


      # order of tabs --------------------------------
        toolsTab,
        gene_expressions_sign_tab,
        genomic_tab,
        epigenetics_tab,
        immune_oncology_tab,
        pharma_tab,
        cell_line_selection_tab,
        mouse_tab,
        multiomics_tab,
        other_tab

    )
  )


}

#         # navbarMenu("Info",
#         #            aboutTab
#                    # definitionsTab)#         )
# #
#        ) # close navbarPage
#     )
#    # )# close taglist
# }





#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources
#' @noRd
golem_add_external_resources <- function() {
  golem::add_resource_path(
    "www",
    app_sys("app/www")
  )

  tags$head(
    favicon("www/bftb_logo_v8_bare.png"),
    bundle_resources(
      path = app_sys("app/www"),
      app_title = "bftb"
    )
    # Add here other external resources
    # for example, you can add shinyalert::useShinyalert()
  )
}

And all the tabs like toolsTab, gene_expressions_sign_tab, genomic_tab, are having each a script.

For example, toolsTab (landing_page.html not provided) has this:

toolsTab <- shiny::tabPanel(
  shiny::tags$div(
    shiny::tags$div(class = "fa fa-tools", role = "navigation"),
    "Tools"
  ),
  # wrap in div for screenreader / accessibility purposes
  value = "tools",
  # tab ID
  cicerone::use_cicerone(),
  # guided tour
  htmltools::htmlTemplate(
    "www/landing-page.html",
    # html file containing landing page contents
    # variables defined in landing-page.html file to be built in Rshiny.
    latest_updates_button = shiny::actionButton('btn_indicator_updates', "View recent updates", class = "button") #,
    #see_more_button = actionButton("jump_to_life_exp", "View life expectancy by SIMD", class = "button"),
    #guide_button = actionButton("guide", "Need help? Take a guided tour", class = "hero-button")
  )
)

And gene_expression_sign_tab has another script, here it is:

gene_expressions_sign_tab <- shiny::tabPanel(
  "Gene Expression",
  icon = icon("chart-line"),
  value = "Gene",
  wellPanel(
    fluidRow(
      shiny::headerPanel(h3("Gene Expression Analysis")),
      br(),
      column(
        3,
        thumbnail_label(
          url = "https://rstudio-connect.scp.astrazeneca.net/RStudio_FLAT/",
          image = "www/FluidigmAnalysisToolkit.v2.png",
          tool = "Fludigm_Browser",
          label = "Fludigm Browser",
          content = "Perform Fluidigm data analysis"
        )
      ),
      column(
        3,
        thumbnail_label(
          url = "https://gtexportal.org/home",
          image = "www/gtex.png",
          tool = "GTEx",
          label = "GTEx Portal",
          content = "Gene expression in normal tissue"
        )
      ),
      # shiny::headerPanel(h2("")),
      column(
        3,
        thumbnail_label(
          url = "https://azcollaboration.sharepoint.com/:b:/r/sites/BioinformaticsfortheBench/Shared%20Documents/Tools/BioTuring/BioTuring_Installation_Instructions.v2021.5.17.pdf?csf=1&web=1&e=TVpy8S",
          image = "www/bioturing.svg",
          content = "Platform for single-cell analysis and spatial transcriptomics exploration",
          label = "BioTuring",
          tool = "BioTuring"
        )
      ),
      column(
        3,
        thumbnail_label(
          url = "http://informatics.medimmune.com/shiny/scope/",
          image = "www/scope.svg",
          content = "Explore available single cell RNA-Seq studies",
          label = "SCOPE",
          tool = "SCOPE"
        )
      ),
      br(),
      shiny::headerPanel(h3("Pathway Analysis")),
      br(),
      column(
        3,
        thumbnail_label(
          url = "https://clarivate.com/cortellis/learning/clarivate-for-astrazeneca1796/",
          image = "www/clarivate.png",
          tool = "clarivate",
          label = "Clarivate",
          content = "Pathway analysis tools from Cortellis including MetaCore"
        )
      ),
      column(
        3,
        thumbnail_label(
          url = "https://analysis.ingenuity.com/pa/launch.jsp",
          image = "www/ipa.png",
          tool = "IPA",
          label = "Ingenuity Pathway Analysis",
          content = "Analyze data using manually curated gene sets"
        )
      ),
      column(
        3,
        thumbnail_label(
          url = "https://astrazeneca.onramp.bio",
          image = "www/onramp.png",
          tool = "OnRamp",
          label = "OnRamp - Rosalind",
          content = "Interactively explore RNA-seq and ChIP-Seq data"
        )
      ),
      br(),
      column(
        3,
        thumbnail_label(
          url = "http://software.broadinstitute.org/gsea/msigdb/index.jsp",
          image = "www/gsea.png",
          tool = "GSEA",
          label = "GSEA",
          content = "Gene set enrichment analysis"
        )
      ),
      br()
    )
  )
)

##################################################################### Updated code based on the bellow suggestion just for clarification #####################################################################

This is what I've tried:

    app_ui <- function(request) {
  tagList(
    # Leave this function for adding external resources
    golem_add_external_resources(),
    shinyjs::useShinyjs(),
    # Include shinyjs
    shiny::bootstrapPage(
      # # add PHS logo to navigation bar
      # title = div(tags$a(
      #   img(src = "www/bftb_logo_v8_bare.png", height = "40px"),
      #   "AZ Oncology Bioinformatics Toolbox"
      # )),

      # make navigation bar collapse on smaller screens
      # windowTitle = "AstraZeneca Oncology profiles",
      # collapsible = TRUE,

      # header = tags$head(
      #   # sourcing css style sheet
      #   includeCSS("www/style.css"),
      #
      #   # include scotpho icon in web browser
      #   HTML("<html lang='en'>"),
      #   tags$link(rel = "shortcut icon",
      #             href = "bftb_logo_v8_bare.ico"),
      #
      #   # include google analytics scripts
      #   # includeScript("google-analytics.js"), # GA 3
      #   # HTML('<script async src="https://www.googletagmanager.com/gtag/js?id=G-KE1C59RLNS"></script>'),
      #   # includeScript("gtag.js") # Google analytics 4
      #
      # ),


      # order of tabs --------------------------------
      tabsetPanel(id = "mainTab",
                  tabPanel(toolsTab, tabsetPanel(id = toolsTab,
                                                 tabPanel("gene_expressions_sign_tab",value=1),
                                                 tabPanel("genomic_tab",value=2),
                                                 tabPanel("epigenetics_tab",value=3),
                                                 selected = 1
                  )),
                  tabPanel("Info", tabsetPanel(id = "Info",
                                               tabPanel(workflowsTab,value=1),
                                               selected = 1))
      )
    )
  )

}

And the app_server is this:

app_server <- function(input, output, session) {
  current_subtab <- reactiveValues(selected = 1)


  # when either sub tabPanel change, save the current selected sub tabPanel to reactiveValues
  observeEvent(c(input$toolsTab, input$'Info'), {
    if (input$mainTab == toolsTab) {
      current_subtab$selected <- input$toolsTab
    } else if (input$mainTab == "Info") {
      current_subtab$selected <- input$'Info'
    }
  })

  # when main tabPanel changed, update the default select subPanel value
  observeEvent(input$mainTab, {
    if (input$mainTab == toolsTab) {
      updateTabsetPanel(session, toolsTab, selected = current_subtab$selected)
    } else if (input$mainTab == "Info") {
      updateTabsetPanel(session, "Info", selected = current_subtab$selected)
    }
  })
}

And this is the error:

Warning: Error in exists: invalid first argument
  93: exists
  92: self$exists
  91: oldInputs$available
  90: shiny::restoreInput
  89: tabsetPanel_
  88: func
  86: tabsetPanel

Solution

  • Put your

    toolsTab,
    gene_expressions_sign_tab,
    genomic_tab,
    epigenetics_tab,
    immune_oncology_tab,
    pharma_tab,
    cell_line_selection_tab,
    mouse_tab,
    multiomics_tab,
    other_tab
    

    Under tabsetPanel with 2 id Tools and Others

    Then use a reactiveValues to check user is under which tabsetPanel, then use updateTabsetPanel to show different tabset panel