rstudio / shinydashboard

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

Active tab fails to display on init when menu and tabs are dynamically generated #319

Open wkdavis opened 5 years ago

wkdavis commented 5 years ago

This is a similar case to #71, but when the body of the dashboard is also dynamically generated the app fails to display the content of the first tab, even when selected = TRUE.

library(shiny)
library(shinydashboard)
ui <- dashboardPage(
  dashboardHeader(title = "Dynamic sidebar"),
  dashboardSidebar(
    sidebarMenu(id="tabs",
                sidebarMenuOutput("menu")
    )
  ),
  dashboardBody(
    uiOutput("body")
  )
)
server <- function(input, output,session) {

  output$menu <- renderMenu({
    sidebarMenu(
      menuItem("Menu item1", tabName="m1", icon = icon("calendar"),selected = TRUE),
      menuItem("Menu item2", tabName="m2", icon = icon("database"))
    )
  })

  output$body <- renderUI({
    tabItems(
      tabItem(tabName = "m1", p("Menu content 1") ),
      tabItem(tabName = "m2", p("Menu content 2") )
    )
  })
}
shinyApp(ui, server)

Session info:

> sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.5

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shinydashboard_0.7.1 shiny_1.3.2         

loaded via a namespace (and not attached):
 [1] compiler_3.6.0   magrittr_1.5     R6_2.4.0         rsconnect_0.8.13 promises_1.0.1   later_0.8.0      htmltools_0.3.6  tools_3.6.0     
 [9] Rcpp_1.0.1       jsonlite_1.6     digest_0.6.18    xtable_1.8-4     httpuv_1.5.1     mime_0.6         rlang_0.3.4     

I dug into the HTML and it looks like it recognizes that the tab should be active, based on the class of the item in the sidebar menu (<li class="active">).

<ul class="sidebar-menu">
  <ul id="menu" class="shinydashboard-menu-output shiny-bound-output sidebar-menu">
    <li class="active">
      <a href="#shiny-tab-m1" data-toggle="tab" data-value="m1" data-start-selected="1" aria-expanded="true">
        <i class="fa fa-calendar"></i>
        <span>Menu item1</span>
      </a>
    </li>
    <li>
      <a href="#shiny-tab-m2" data-toggle="tab" data-value="m2">
        <i class="fa fa-database"></i>
        <span>Menu item2</span>
      </a>
    </li>
  </ul>
  <div id="tabs" class="sidebarMenuSelectedTabItem shiny-bound-input" data-value="m1"></div>
</ul>

But when I inspect the actual panel:

<div role="tabpanel" class="tab-pane" id="shiny-tab-m1">
    <p>Menu content 1</p>
</div>

I find that it has class "tab-pane" when I think the class should be "active" based on the css (this is line 4137-4142 from bootstrap.css):

.tab-content > .tab-pane {
  display: none;
}
.tab-content > .active {
  display: block;
}

from the following version of bootstrap:

/*!
 * Bootstrap v3.3.7 (http://getbootstrap.com)
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
kevin041811 commented 4 years ago

Interestingly if you change the outputID in ui and the output$body to text other than "body", it works. not sure why.

uiOutput("body2")

wkdavis commented 4 years ago

@kevin041811 That's an interesting observation. It made me think that it has something to do with the fact that "body" is also an HTML tag, so I tried a few other examples.

I'm thinking there is some fuzzy-matching logic going on somewhere that is looking for HTML tags or something like HTML tags, but I'm not sure. For instance, I don't know why body2 works but div2 does not.

homer3018 commented 4 years ago

This looks very similar to what I've reported earlier today (#335), might be a duplicate.

homer3018 commented 4 years ago

Hello, I'm not too sure how I would translate this fix (rename body into anything different in uiOutput(body), since I already use something different (uiOutput(TABUI) which is hosting all my tabItems). Have you got by any chance to the bottom of this ? I'm still stuck with this issue which I describe also in #335 .

Thanks ahead of time for your help :)

kaijagahm commented 3 years ago

I'm having a similar problem, except my UI isn't dynamically generated--but even when I add a static UI component as a menuSubitem or just by itself under one of the menuItems, the selected tab does not display on init. I posted about this issue here on RStudio community, along with a reproducible UI example. Is there a fix for this yet?

Thank you!

homer3018 commented 3 years ago

Have a look at #71, basically adding

isolate({updateTabItems(session, "sidebarmenu_id", "init_tabname")})

should do the trick with sidebarmenu_id being the id of my sidebarmenu, and init_tabname the tabName of the tab I should get upon firing the app.

kaijagahm commented 3 years ago

Thank you so much for the response @homer3018! You're right that this fix works really well to get the menuItem to display initially (which is awesome). However, for some reason the menuItem still doesn't read as "selected" from the server's point of view, which means that when I write other code that depends on input$sidebarmenu_id being equal to init_tabname (i.e. code that depends on which menuItem is selected), that code won't work. Here is an example, where I've just added a bit in the server to print a message to the console when each menuItem is selected. You'll see that even while the first tab, "mapView", does now open on init, no matter how much I click between the two tabs you will never see the message "Map view has been selected" in the console, and on init the "Social variables view has been selected" message displays even though the map view tab shows up:

library(shinyjs)
library(shinyWidgets)
library(shinydashboard)
library(shinydashboardPlus)
library(dashboardthemes)
source("dashboardFunctions.R")

ui <- dashboardPagePlus(
  useShinyjs(),

  ## Define dashboard header: title, icon for right sidebar, etc.
  header = dashboardHeaderPlus(
    title = "Dashboard",
    enable_rightsidebar = TRUE,
    rightSidebarIcon = "sliders"
  ),

  ## Define left sidebar and menu options
  sidebar = dashboardSidebar(
    sidebarMenu(
      id = "leftSidebar",
      menuItem("Map view", tabName = "mapView", icon = icon("map"), selected = TRUE, startExpanded = TRUE,
               # add a menuSubItem
               selectInput("survey", "Survey",
                           choices = c("5", "5b", "6", "6b", "7", "8", "9", "11", "12"),
                           selected = "11",
                           multiple = FALSE)
      ),
      menuItem("Social variables", tabName = "socialVariables", icon = icon("gears"))
    )
  ),

  ## Define dashboard body (maps/graphs)
  body = dashboardBody(
    shinyDashboardThemes(theme = "grey_dark"
    ),
    tabItems(tabItem(tabName = "map", p("[Insert map here]")),
             tabItem(tabName = "socialCharts", p("[Insert charts here]"))
    )
  )
)

server <- function(session, input, output) {
  observe({
    if(req(input$leftSidebar) == "mapView"){
      message("Map view has been selected.")
    }else if(req(input$leftSidebar) == "socialVariables"){
      message("Social variables view has been selected.")
    }
  })
  isolate({updateTabItems(session, "leftSidebar", "mapView")})

}

shinyApp(ui = ui, server = server)
ismirsehregal commented 3 years ago

I answered the above here.

Franco1605 commented 1 year ago

@kaijagahm i have the same problem... when i run the app, the first tab (or menu item) is selected, but the content do not load in the body... did you find the solution ?

kaijagahm commented 1 year ago

Honestly, it was so long ago that I barely remember. I think I used the solution described in the post linked right above your comment: https://community.rstudio.com/t/shinydashboard-wrong-menuitem-selected-after-adding-menusubitem/82561/3?u=ismirsehregal. Did you already try that?