1

Inside shiny ui.R, while working with a dashboardPage(), my dashboardHeader() has a dropdown-menu referenced to a list:

dropdownMenu(type = "messages",.list=Mylist)

Where Mylist is filled with messageItem()'s.

But instead of using dashboardBody() and tabItems(), I'm using something like this:

tags$div(class="content-wrapper",
         conditionalPanel('condition',tags$section(...)))
         ,
         conditionalPanel('condition',tags$section(class="content",...))
         ) 

So that I could avoid the margins when creating a leafletOutput().

My question is, how can I get my conditionalPanel() to use the click on any (or specific) message as a condition?

Same thing for taskItems() and notificationItems().

1 Answers1

1

I think what you're asking is: "How can I access the latest item (in a dropdown menu) that the user clicked?"

If that is the question, then I have to tell you that, unfortunately, shinydashboard doesn't support this (for now, at least). There is an issue currently open in shinydashboard's Github repo that would make this possible, but I can't tell you if/when we'd implement that... I'd recommend using a different condition mechanism (ideally something that is tracked by Shiny and accessible by input$). This is possible for the sidebarMenu(), which is made up of menuItem()s (as long as you provide an id to sidebarMenu() and a tabName to all the childless menuItem()s -- read more about that here). You said that you were not using dashboardBody() and tabItems() "so that I could avoid the margins when creating a leafletOutput()." I think it'd probably be a lot easier to handle the CSS for those cases, but stick to functionality provided by shinydashboard out of the box, than the reverse.


If you really want this, there is a workaround using the href argument of messageItem() (also present in taskItem() and notificationItem()). This is a bit clunky because you have to keep track of all the hrefs and you'd be updating the URL (in the example below, the hash), each time that you click on an item. If you do that though, now you have an event that you can listen to. However, you can't use conditional panels, since getUrlHash() must be called on the server (it needs to access the session object), not on the ui.

Again, this is a workaround. If you can, you should try to use a mechanic that is fully supported in shinydashboard (less chance of your app breaking or changing in future versions of the package).

Workaround using href argument to messageItem:

library(shiny)
library(shinydashboard)

# these must be unique and exist for every item
itemIds <- c(team = "#team", team2 = "#team2", user = "#user")

ui <- dashboardPage(
  dashboardHeader(
    dropdownMenu(type = "messages", badgeStatus = "success",
      messageItem("Support Team", "This is the content of a message.",
        time = "5 mins", href = itemIds[["team"]]
      ),
      messageItem("Support Team", "This is the content of another message.",
        time = "2 hours", href = itemIds[["team2"]]
      ),
      messageItem("New User", "Can I get some help?",
        time = "Today", href = itemIds[["user"]]
      )
    )
  ),
  dashboardSidebar(),
  dashboardBody(
    sliderInput("sld", "This is here so you know that other inputs are not affected by this workaround", 0, 100, 50),
    uiOutput("ui")
  )
)

server <- function(input, output, session) { 
  output$ui <- renderUI({
    hash <- getUrlHash()
    if (hash %in% itemIds) {
      paste("This is shown when", hash, "is clicked")
    }
  })
}

shinyApp(ui, server)
Bárbara Borges
  • 889
  • 7
  • 15