简体   繁体   中英

updateTabsetPanel to navigate between nested tabsetPanels in Shiny app

I would like to be able to use an actionLink to navigate to tabPanel s within nested tabsetPanel s. I'm currently only able to navigate to the specific tabPanel if I already have the parent tabPanel selected. This nomenclature gets confusing quite quickly, so here's an example that has nested tabPanels , and two actionLink s to navigate to two of the child tabPanel s:

library(shiny)

ui <- {
    fluidPage(
        fluidRow(
            column(3,
                actionLink('subpanel_1a', 'Go to 1 A'),
                br(),
                actionLink('subpanel_1b', 'Go to 1 B')
            ),
            column(9,
                tabsetPanel(id = 'master_panel',
                    tabPanel('Primary panel 1',
                        tabsetPanel(id = 'primary_panel_1',
                            tabPanel('subpanel_1_a'),
                            tabPanel('subpanel_1_b')
                        )
                    ),
                    tabPanel('Primary panel 2',
                        tabsetPanel(id = 'primary_panel_2',
                            tabPanel('subpanel_2_a'),
                            tabPanel('subpanel_2_b')
                        )
                    )
                )
            )
        )
    )
}

server <- function(input, output, session) {
    observeEvent(input$subpanel_1a, {
        updateTabsetPanel(session, 'primary_panel_1', 'subpanel_1_a')
    })
    observeEvent(input$subpanel_1b, {
        updateTabsetPanel(session, 'primary_panel_1', 'subpanel_1_b')
    })
}

shinyApp(ui, server)

The actionLink s 'Go to 1 A' and 'Go to 1 B' only work if the currently selected parent tabPanel is 'Primary panel 1'---they don't work if you are in 'Primary panel 2'.

Is there a way to bypass this behaviour to have actionLink s that work regardless of your currently selected panel?

You could use the same "update-logic" for your master_panel , before updating the subpanel.

So for 2a it would read:

observeEvent(input$subpanel_2a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_a')
  })

Reproducible code:

library(shiny)

ui <- {
  fluidPage(
    fluidRow(
      column(3,
             actionLink('subpanel_1a', 'Go to 1 A'),
             br(),
             actionLink('subpanel_1b', 'Go to 1 B'),
             br(),
             actionLink('subpanel_2a', 'Go to 2 A'),
             br(),
             actionLink('subpanel_2b', 'Go to 2 B')
      ),
      column(9,
             tabsetPanel(id = 'master_panel',
                         tabPanel('Primary panel 1',
                                  tabsetPanel(id = 'primary_panel_1',
                                              tabPanel('subpanel_1_a'),
                                              tabPanel('subpanel_1_b')
                                  )
                         ),
                         tabPanel('Primary panel 2',
                                  tabsetPanel(id = 'primary_panel_2',
                                              tabPanel('subpanel_2_a'),
                                              tabPanel('subpanel_2_b')
                                  )
                         )
             )
      )
    )
  )
}

server <- function(input, output, session) {
  observeEvent(input$subpanel_1a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 1')
    updateTabsetPanel(session, inputId = 'primary_panel_1', selected = 'subpanel_1_a')
  })

  observeEvent(input$subpanel_1b, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 1')
    updateTabsetPanel(session, inputId = 'primary_panel_1', selected = 'subpanel_1_b')
  })

  observeEvent(input$subpanel_2a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_a')
  })

  observeEvent(input$subpanel_2b, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_b')
  })
}

shinyApp(ui, server)

Following this way you might create quite some repetitive code.

Depending on the amount of panels and subpanels you have you could try to choose names that would allow you avoid very repetitive code for this updates. So if you have panel_1 and panel_1_a to panel_5 and panel_5_d . You could dynamically read the "levels" from the strings. The logic would be panel_{FIRSTLEVELNR}_{SECONDLEVELNR} . Then you can use sthg like:

library(magrittr)
levels = panel_{FIRSTLEVELNR}_{SECONDLEVELNR} >%> strsplit(split = "_") %>% unlist
updateTabsetPanel(session, inputId = 'master_panel', selected = levels[2])
updateTabsetPanel(session, inputId = 'primary_panel_1', selected = levels[3])

dynamically for all panel+subpanel instead of repeating that 20 times. But like i said, it depends on the amount of panel+subpanel you have and the desired naming conventions.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM