rstudio / shinydashboard

Shiny Dashboarding framework
https://rstudio.github.io/shinydashboard/
Other
892 stars 300 forks source link

Only run `ensureActivatedTab()` after `renderMenu()` for sidebarMenus #233

Closed bborgesr closed 7 years ago

bborgesr commented 7 years ago

Fixes [#229]: only run ensureActivatedTab() after renderMenu() is called if the el in question has class "sidebar-menu". Since this function is used for both dropdownMenuOutput and sidebarMenuOutput, we have to make sure that ensureActivatedTab() is only called if it's the latter case (otherwise, you get unexpected tab redirections when updating a dropdown menu).

We only started calling ensureActivatedTab() after a renderMenu() call in commit 18b3505603def0aae350fb09364d9c25d6ddc47a. This fixed a long-time bug that unselected/deactivated all tabs when you dynamically created a sidebar menu. This example illustrates the problem (i.e. before this fix, nothing would be selected):

app.R ```r library(shiny) library(shinydashboard) ui <- dashboardPage( dashboardHeader(title = "Dynamic sidebar"), dashboardSidebar( sidebarMenuOutput("menu") ), dashboardBody(tabItems( tabItem(tabName = "dashboard", h2("Dashboard tab content")) )) ) server <- function(input, output) { output$menu <- renderMenu({ sidebarMenu(id="mytabs", menuItem("Menu item", tabName="dashboard", icon = icon("calendar")) ) }) } shinyApp(ui, server) ```


However, this introduced a new bug for all other menus that use the renderMenu() function, in addition to the sidebarMenu(). As issues #229 and #232 show, this code results in weird tab redirections when you use renderValue() to render another type of menu (in those issues, that was a dropdownMenu()).

This PR fixes this second issue (while making sure that the first issue does not resurface). It does so quite simply: inside renderValue(), check if el has the class "sidebar-menu" and only then, call ensureActivatedTab().

It also adds another manual test to be repro this issue in the future. Before this fix, you would observe that when the selected tab is not the first, and the renderMenu() is invalidated, the first tab gets selected. This was particularly annoying in the app below:

app.R ```r library(shiny) library(shinydashboard) # When the selected tab is not the first, and the renderMenu # is invalidated, the first tab gets selected. Here is an # example: If you type something inside the textInput called # "foo" (on tab2), tab1 is selected. ui <- dashboardPage( dashboardHeader( title = NULL, dropdownMenuOutput("top") ), dashboardSidebar( sidebarMenu( menuItem("Tab1", tabName = "tab1"), menuItem("Tab2", tabName = "tab2") ) ), dashboardBody( tabItems( tabItem(tabName = "tab1", h1("tab1") ), tabItem(tabName = "tab2", h1("tab2"), textInput("foo", "Type something", "") ) ) ) ) server <- shinyServer(function(input, output, session) { output$top <- renderMenu({ tags$li(class = "dropdown", if (input$foo == "") { "text1" } else { "text2" } ) }) }) shinyApp(ui, server) ```