Search code examples
javascriptrshinynavbar

Auto-close collapsed R Shiny navbarPage


I have an R Shiny app with a collapsed navbarPage as described here. Now I would appreciate to have the menu collapsing on its own as soon as the cursor moves away from it rather than collapsing it manually. I have seen a couple of solutions for other frameworks, but does someone know how to solve this with R Shiny?

A simple example app here:

library(shiny)

navbar_js <- "@media (max-width: 12000px) {
    .navbar-header {
        float: none;
    }
    .navbar-left,.navbar-right {
        float: none !important;
    }
    .navbar-toggle {
        display: block;
    }
    .navbar-collapse {
        border-top: 1px solid transparent;
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
    }
    .navbar-fixed-top {
        top: 0;
        border-width: 0 0 1px;
    }
    .navbar-collapse.collapse {
        display: none!important;
    }
    .navbar-nav {
        float: none!important;
        margin-top: 7.5px;
    }
    .navbar-nav>li {
        float: none;
    }
    .navbar-nav>li>a {
        padding-top: 10px;
        padding-bottom: 10px;
    }
    .collapse.in{
        display:block !important;
    }
}"

ui <- navbarPage("App title",
                 collapsible = TRUE,
                 tabPanel("Panel 1"),
                 tabPanel("Panel 2"),
                 tabPanel("Panel 3"),
                 tags$head(tags$style(HTML(navbar_js))))

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Thank you :)


Solution

  • Some time and many JavaScript lessons later, I figured out how to write a jQuery snippet that hides the extended navbar when (i) clicking onto a link within the navbar (but still opens toggle menus inside the navbar) and (ii) clicking anywhere outside the navbar. :)

    library(shiny)
    
    navbar_js <- "@media (max-width: 12000px) {
        .navbar-header {
            float: none;
        }
        .navbar-left,.navbar-right {
            float: none !important;
        }
        .navbar-toggle {
            display: block;
        }
        .navbar-collapse {
            border-top: 1px solid transparent;
            box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
        }
        .navbar-fixed-top {
            top: 0;
            border-width: 0 0 1px;
        }
        .navbar-collapse.collapse {
            display: none!important;
        }
        .navbar-nav {
            float: none!important;
            margin-top: 7.5px;
        }
        .navbar-nav>li {
            float: none;
        }
        .navbar-nav>li>a {
            padding-top: 10px;
            padding-bottom: 10px;
        }
        .collapse.in{
            display:block !important;
        }
    }"
    
    
    ui <- fluidPage(
      tags$head(
        tags$script("// Autoclose navbar
                    $(document).click(function (event) {
                      // after click into navbar
                      if ($(event.target).is('.navbar-collapse a:not(.dropdown-toggle)')) {
                        $('.navbar-collapse').collapse('hide');
                      }
                      // after click anywhere outside navbar
                      if (!$(event.target).is('.navbar-collapse *')) {
                        $('.navbar-collapse').collapse('hide');
                      }
                    });")
      ),
      navbarPage("App with autocollapsing navbar :)",
                 collapsible = TRUE,
                 tabPanel("Panel 1"),
                 tabPanel("Panel 2"),
                 navbarMenu("Panel 3",
                            tabPanel("Panel 3a"),
                            tabPanel("Panel 3b")),
                 tabPanel("Panel 4"),
                 tags$head(tags$style(HTML(navbar_js))))
      )
    
    server <- function(input, output) {}
    
    shinyApp(ui = ui, server = server)