如何在Shiny App折叠/展开侧边栏时控制主面板宽度
修复Shiny App侧边栏切换后主面板布局异常问题
你的问题是:点击切换按钮折叠侧边栏时主面板宽度能扩展到100%,但再次展开侧边栏时,主面板宽度无法恢复,且显示在侧边栏下方。这是因为原代码中依赖input$toggle_btn的点击次数判断状态逻辑错误,且直接修改width破坏了Bootstrap的网格布局。
修改方案
使用Shiny标准的sidebarLayout来维护布局结构,配合reactiveVal跟踪侧边栏状态,调整主面板的列类来适配布局:
library(shiny) library(bsplus) library(shinyjs) ui <- fluidPage( useShinyjs(), tags$style(HTML( "#mainPanel { background-color: blue; color: white; }" )), titlePanel("Toggler"), # 用sidebarLayout包裹侧边栏和主面板,维持默认网格布局 sidebarLayout( sidebarPanel( id = "sidebar", bs_accordion( id = "accordion" ) %>% bs_set_opts( use_heading_link = TRUE ) %>% bs_append( title = tags$div(tags$i(class = "fa-solid fa-upload"),"Upload"), content = fileInput("upload", "Upload a Excel File", accept = c(".xlsx",".csv")) ) , use_bs_accordion_sidebar() ), mainPanel( id = "mainPanel", actionButton("toggle_btn", "Toggle") ) ) ) server <- function(input, output, session) { options(shiny.maxRequestSize = 100*1024^2) # Upload file Size Limit (100mb) session$onSessionEnded(function() { stopApp() }) # 用reactiveVal跟踪侧边栏的可见状态 sidebar_visible <- reactiveVal(TRUE) observeEvent(input$toggle_btn, { # 切换侧边栏状态 sidebar_visible(!sidebar_visible()) shinyjs::toggle(id = "sidebar", condition = sidebar_visible()) # 根据状态调整主面板的列类,适配Bootstrap网格 if (!sidebar_visible()) { runjs('$("#mainPanel").parent().removeClass("col-sm-9").addClass("col-sm-12");') } else { runjs('$("#mainPanel").parent().removeClass("col-sm-12").addClass("col-sm-9");') } }) } shinyApp(ui, server)
关键改动说明
- 使用
sidebarLayout:这是Shiny的标准布局组件,默认会将侧边栏设为3列(col-sm-3)、主面板设为9列(col-sm-9),保证布局的联动性。 - 用
reactiveVal跟踪状态:避免依赖input$toggle_btn的递增点击次数,准确判断侧边栏当前是展开还是折叠状态。 - 调整列类而非直接改width:通过修改主面板父容器的Bootstrap列类,让布局自动适配侧边栏的显示/隐藏,确保主面板能回到原位置和宽度。
内容的提问来源于stack exchange,提问作者Golem
相关产品推荐
相关产品推荐

