Search code examples
javascriptcssrshinyshinydashboard

How to expand/collapse the shiny dashboard sidebar on mouse hover?


Within a Shiny Dashboard, I would like that mouse hover the mini-sidebar expands it. When mouse leaves the sidebar it then collapse automatically in its original state (mini-sidebar).

The closest answer I get right now is by using the expand/collapse default button function with a mouse hover using a JQuery (see code below) but I would like this effect to be extend for the whole sidebar (thanks to How to make appear sidebar on hover instead of click in Shiny?)

I guess that one way to do that is by triggering the a.sidebar-toggle click action on sidebar mouse hover, but I have been unable to find the sidebar object class to observe a mouseover on it.

tags$head(tags$script(HTML("$(function() {$('the sidebar object').mouseover(function(e) { $(a.sidebar-toggle).click()})});")))

Minimal example:

library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
shinyApp(
  ui = dashboardPagePlus(
    header = dashboardHeaderPlus(
      enable_rightsidebar = TRUE,
      rightSidebarIcon = "gears"
    ),
    sidebar = dashboardSidebar(
      sidebarMenu(
        menuItem("DASHBOARD1", tabName = "Spectrum", icon = icon("table")
        ), #menuItem
        menuItem("DASHBOARD2", tabName = "LTE", icon = icon("mobile-alt"))        
      )),
    body = dashboardBody(),
    title = "TEST",
    tags$head(tags$script(HTML("$(function() { $('a.sidebar-toggle').mouseover(function(e) { $(this).click()})});"))),

  ),
  server = function(input, output) { }
)

Solution

  • Here is a library(shinyjs) solution:

    library(shiny)
    library(shinydashboard)
    library(shinydashboardPlus)
    library(shinyjs)
    
    shinyApp(
      ui = dashboardPagePlus(
        header = dashboardHeaderPlus(enable_rightsidebar = TRUE,
                                     rightSidebarIcon = "gears"),
        sidebar = dashboardSidebar(
          sidebarMenu(
            id = "sidebar_id",
            menuItem("DASHBOARD1", tabName = "Spectrum", icon = icon("table")),
            menuItem("DASHBOARD2", tabName = "LTE", icon = icon("mobile-alt"))
          )
        ),
        body = dashboardBody(
          useShinyjs()
          ),
        title = "TEST"
      ),
      server = function(input, output, session) {
        onevent("mouseenter", "sidebarCollapsed", shinyjs::removeCssClass(selector = "body", class = "sidebar-collapse"))
        onevent("mouseleave", "sidebarCollapsed", shinyjs::addCssClass(selector = "body", class = "sidebar-collapse"))
      }
    )
    

    Result


    Edit:

    As mentioned by @yeahman269 this is now an official feature of library(shinydashboardPlus). It can be actiivated by using the option sidebarExpandOnHover = TRUE.

    library(shiny)
    library(shinydashboard)
    library(shinydashboardPlus)
    shinyApp(
       ui = dashboardPage(
         options = list(sidebarExpandOnHover = TRUE),
         header = dashboardHeader(),
         sidebar = dashboardSidebar(minified = TRUE, collapsed = TRUE),
         body = dashboardBody(
          lapply(1:20, box, width = 12, title = "box")
         ),
         controlbar = dashboardControlbar(),
         title = "DashboardPage"
       ),
       server = function(input, output) { }
     )
    

    Example taken from here.