9
votes

I have a shiny app with a mainPanel and a sidebarPanel inside a tabPanel in a navbarPage. I need an option to hide the sidebarPanel similar to this: Hide sidebar in default in shinydashboard and https://github.com/daattali/shinyjs/issues/43.

An actionButton should control if the sidebarPanel is shown or collapsed.

This is the code:

library(shiny)
library(shinyjs)

ui <- fluidPage(
  navbarPage("",
             tabPanel("tab",
                      sidebarPanel(
                        useShinyjs()
                      ),

                      mainPanel(actionButton("showSidebar", "Show sidebar"),
                                actionButton("hideSidebar", "Hide sidebar")
                      )
             )
  )
)

server <-function(input, output, session) {
  observeEvent(input$showSidebar, {
    shinyjs::removeClass(selector = "body", class = "sidebarPanel-collapse")
  })
  observeEvent(input$hideSidebar, {
    shinyjs::addClass(selector = "body", class = "sidebarPanel-collapse")
  })
}

shinyApp(ui, server)

Hope somebody can help :)

3

3 Answers

15
votes

I have modified your code to hide and show the sidebar. To create the id for the sidebarPanelI have enclosed it within div and given it theid = Sidebar. To show and hide the side bar I have used shinyjs function show and hide with the id as Sidebar.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage("",
             tabPanel("tab",
                      div( id ="Sidebar",sidebarPanel(
                      )),


                      mainPanel(actionButton("showSidebar", "Show sidebar"),
                                actionButton("hideSidebar", "Hide sidebar")
                      )
             )
  )
)

server <-function(input, output, session) {
  observeEvent(input$showSidebar, {
    shinyjs::show(id = "Sidebar")
  })
  observeEvent(input$hideSidebar, {
    shinyjs::hide(id = "Sidebar")
  })
}

shinyApp(ui, server)  

Hope it helps!

3
votes

An example of the toggle option suggested in previous comments.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage("",
             tabPanel("tab",
                      div( id ="Sidebar",sidebarPanel(
                      )),


                      mainPanel(actionButton("toggleSidebar", "Toggle sidebar")
                      )
             )
  )
)

server <-function(input, output, session) {
  observeEvent(input$toggleSidebar, {
    shinyjs::toggle(id = "Sidebar")
  })
}

shinyApp(ui, server)
1
votes

I made an example with toggle button on navbar and multiple tabs.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage(title = tagList("title",actionLink("sidebar_button","",icon = icon("bars"))),
             id = "navbarID",
             tabPanel("tab1",
                      div(class="sidebar"
                          ,sidebarPanel("sidebar1")
                      ),
                      mainPanel(
                        "MainPanel1"
                      )
             ),
             tabPanel("tab2",
                      div(class="sidebar"
                          ,sidebarPanel("sidebar2")
                      ),
                      mainPanel(
                        "MainPanel2"
                      )
             )
  )
)

server <-function(input, output, session) {
  
  observeEvent(input$sidebar_button,{
    shinyjs::toggle(selector = ".sidebar")
  })
  
}

shinyApp(ui, server)

=======================================

I have created a simpler example that does not use the sidepanel class, but I am not sure if it will work in all environments.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage(title = tagList("title",actionLink("sidebar_button","",icon = icon("bars"))),
             tabPanel("tab1",
                      sidebarPanel("sidebar1"),
                      mainPanel("MainPanel1")
             ),
             tabPanel("tab2",
                      sidebarPanel("sidebar2"),
                      mainPanel("MainPanel2")
             )
  )
)

server <-function(input, output, session) {
  observeEvent(input$sidebar_button,{
    shinyjs::toggle(selector = ".tab-pane.active div:has(> [role='complementary'])")
  })
}

shinyApp(ui, server)

=======================================

I've finally finished my collapsible sidebarpanel, and shinyjs runjs allows you to extend the width of the mainpanel when the sidebarpanel is collapsed.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage(title = tagList("title",actionLink("sidebar_button","",icon = icon("bars"))),
             tabPanel("tab1",
                      sidebarPanel("sidebar1",width=3),
                      mainPanel("MainPanel1",width=9,style="background-color:gray")
             ),
             tabPanel("tab2",
                        sidebarPanel("sidebar2",width=5)
                        ,mainPanel("MainPanel2",width=7,style="background-color:gray")
             )
  )
)

server <-function(input, output, session) {
  observeEvent(input$sidebar_button,{
    shinyjs::toggle(selector = ".tab-pane.active div:has(> [role='complementary'])")
    
    js_maintab <- paste0('$(".tab-pane.active div[role=',"'main'",']")')
    
    runjs(paste0('
          width_percent = parseFloat(',js_maintab,'.css("width")) / parseFloat(',js_maintab,'.parent().css("width"));
          if (width_percent == 1){
            ',js_maintab,'.css("width","");
          } else {
            ',js_maintab,'.css("width","100%");
          }
          '))
  })
}

shinyApp(ui, server)