Reputation: 11431
I have a server generated sidebar. After its creation, I want to hide its first element. The observer doing the hiding is executed, however, the menuitem is not hidden. I am trying to figure out, why it does not work. Any thoughts?
PS. The CSS selector appears to be correct, as all works when the UI is not created on the server.
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
uiOutput("sidebar_ui")
),
dashboardBody(
shinyjs::useShinyjs()
)
)
server <- function(session, input, output)
{
rv <- reactiveValues()
output$sidebar_ui <- renderUI({
rv$trigger_sidebar_config <- 0
cat("\nSidebar create")
sidebarMenu(id = "sidebar",
menuItem("Menu1", tabName = "tab_menu_1"), # to be hidden
menuItem("Menu2", tabName = "tab_menu_2") )
})
observeEvent(rv$trigger_sidebar_config, {
cat("\nSidebar config")
shinyjs::hide(selector = '[data-value="tab_menu_1"]') # hide menuitem
})
}
shinyApp(ui, server)
Upvotes: 0
Views: 902
Reputation: 33397
Your observeEvent
is executed too early because the reactive value trigger_sidebar_config
is updated during the same cycle as renderUI
. Accordingly shiny tries to hide an UI element which isn't existing yet (you would have to wait for the UI beeing rendered, instead of it's calculation beeing triggered, for this to work).
You can test this e.g. via delaying the execution of shinyjs::hide
- it works when triggered by an actionButton
(Please see my below example) or you have a look at the reactlog:
Here you can see, that the observeEvent triggered via trigger_sidebar_config
finished calculating after 3ms but the sidebar wasn't ready at this time (30ms).
If you want the tab to be hidden on startup you can use hidden()
in your renderUI
call (see Menu3
):
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
uiOutput("sidebar_ui")
),
dashboardBody(
shinyjs::useShinyjs(),
actionButton("hide", "hide tab")
)
)
server <- function(session, input, output)
{
rv <- reactiveValues()
output$sidebar_ui <- renderUI({
rv$trigger_sidebar_config <- 0
cat("\nSidebar create")
sidebarMenu(id = "sidebar",
menuItem("Menu1", tabName = "tab_menu_1"), # to be hidden
menuItem("Menu2", tabName = "tab_menu_2"),
shinyjs::hidden(menuItem("Menu3", tabName = "tab_menu_3")))
})
observeEvent(input$hide, {
cat("\nSidebar config")
shinyjs::hide(selector = '[data-value="tab_menu_1"]') # hide menuitem
})
}
shinyApp(ui, server)
In this context please also see ?renderMenu()
.
Upvotes: 1