rstudio / shinydashboard

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

"menuItem()" from "renderMenu()" does not disappear as expected #352

Open romanhaa opened 4 years ago

romanhaa commented 4 years ago

Hi there,

I observed a strange behavior that I can't get behind. In my dashboard, I need one menuItem() to be shown dynamically, depending on whether or not the currently loaded dataset contains the respective content to be shown in that tab. It was quite easy to implement the tab to appear only in case the data is present. However, the tab doesn't disappear when loading a new dataset that doesn't contain the respective data. I made a little reprex with a checkbox that correctly makes a menu item appear when checking the box, but the menu item won't disappear when unchecking the box.

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
    dashboardHeader(title = span("test ")),
    dashboardSidebar(
        sidebarMenu(
            id = "sidebar",
            menuItem("Fixed sidebar item", tabName = "fixed_sidebar_item"),
            menuItemOutput("optional_sidebar_item")
        )
    ),
    dashboardBody(
        tabItems(
            tabItem(
                tabName = "fixed_sidebar_item",
                tagList(
                    textOutput('fixed_sidebar_item_content'),
                    checkboxInput(
                        inputId = 'show_optional_sidebar_item',
                        label = 'Show optional sidebar item',
                        value = FALSE
                    )
                )
            ),
            tabItem(
                tabName = "optional_sidebar_item",
                tagList(
                    textOutput('optional_sidebar_item_content')
                )
            )
        )
    )
)

server <- function(input, output) {

    output[["fixed_sidebar_item_content"]] <- renderText('This is the content of the fixed sidebar item.')

    output[["optional_sidebar_item"]] <- renderMenu({
        if ( input[["show_optional_sidebar_item"]] == TRUE ) {
            menuItem("Optional sidebar item", tabName = "optional_sidebar_item")
        }
    })

    output[["optional_sidebar_item_content"]] <- renderText('This is the content of the optional sidebar item.')

}

shinyApp(ui = ui, server = server)

Screen Shot 2020-09-22 at 11 08 00 Screen Shot 2020-09-22 at 11 08 03 Screen Shot 2020-09-22 at 11 08 05

I would appreciate if somebody would help me understand what I'm doing wrong or if this is a bug.

Thank you!

Session info:

R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Catalina 10.15.6

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  
[7] base     

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

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.5       crayon_1.3.4     packrat_0.5.0   
 [4] digest_0.6.25    withr_2.2.0      later_1.1.0.1   
 [7] mime_0.9         R6_2.4.1         jsonlite_1.7.0  
[10] xtable_1.8-4     magrittr_1.5     rlang_0.4.7     
[13] rstudioapi_0.11  promises_1.1.1   tools_3.6.3     
[16] rsconnect_0.8.16 httpuv_1.5.4     fastmap_1.0.1   
[19] compiler_3.6.3   htmltools_0.5.0
romanhaa commented 4 years ago

For those running into the same problem and looking for a workaround, you can use the shinyJS package to show/hide UI elements. Here is the same app as above, however with bits from shinyJS that listen to the checkbox and toggle the show/hide status of the tab item.

library(shiny)
library(shinydashboard)
library(shinyjs)

ui <- dashboardPage(
    dashboardHeader(title = "test"),
    dashboardSidebar(
        sidebarMenu(
            id = "sidebar",
            menuItem("Fixed sidebar item", tabName = "fixed_sidebar_item"),
            menuItemOutput("optional_sidebar_item")
        )
    ),
    dashboardBody(
        useShinyjs(),
        tabItems(
            tabItem(
                tabName = "fixed_sidebar_item",
                tagList(
                    textOutput('fixed_sidebar_item_content'),
                    checkboxInput(
                        inputId = 'show_optional_sidebar_item',
                        label = 'Show optional sidebar item',
                        value = FALSE
                    )
                )
            ),
            tabItem(
                tabName = "optional_sidebar_item",
                tagList(
                    textOutput('optional_sidebar_item_content')
                )
            )
        )
    )
)

server <- function(input, output) {

    output[["fixed_sidebar_item_content"]] <- renderText('This is the content of the fixed sidebar item.')

    output[["optional_sidebar_item"]] <- renderMenu({
        menuItem("Optional sidebar item", tabName = "optional_sidebar_item")
    })

    output[["optional_sidebar_item_content"]] <- renderText('This is the content of the optional sidebar item.')

    observe({
        toggleElement(
            id = "optional_sidebar_item",
            condition = input[["show_optional_sidebar_item"]]
        )
    })
}

shinyApp(ui = ui, server = server)