闪亮 - 当其中一个面板设置为隐藏时,调整其他面板的大小

时间:2017-05-19 22:38:27

标签: r shiny sidebar shinyjs

我正在使用Shiny来构建一个Web应用程序。我正在添加一个按钮,用于显示/隐藏页面上的某些元素。但是在元素被隐藏之后,其他页面组件不会自己调整大小以填充屏幕。例如,我尝试使用shinyjs中的切换功能隐藏sidebarLayout的侧边栏。这是我的代码:

library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(sidebarLayout(
  sidebarPanel(id="sidebar"),
  mainPanel(wellPanel(actionButton("sideBarControl", label = "Show/Hide")))
)))
server <- function(input, output) {
  observeEvent(input$sideBarControl, {
    shinyjs::toggle(id = "sidebar")
    # potentially some statements here to fix the layout? But what should they be?
  })
}
shinyApp(ui = ui, server = server)

侧边栏隐藏/显示正确单击侧栏控制按钮时,但不是调整主面板大小以填充屏幕,而是将mainPanel移动到左侧,并在右侧留下一个空格。怎么解决这个?见下图:

Before hiding the sidebar

After hiding the sidebar - actual

After hiding the sidebar - expected

2 个答案:

答案 0 :(得分:2)

让我回应我之前建议的评论。由于这与前一个完全不同,我写了一个新答案,而不是编辑它。

通常,您可以通过在控制台上运行命令来检查从UI描述生成的HTML代码。例如,

sidebarPanel(id="sidebar", actionButton("b", "btn"))
##<div class="col-sm-4">
##  <form class="well" id="sidebar">
##    <button id="b" type="button" class="btn btn-default action-button">btn</button>
##  </form>
##</div>

这告诉我们sidebarPanel函数生成

的嵌套框架
  • div,课程为col-sm-4;和
  • form,其中包含提供的内容

您的示例代码没有移动主面板的原因现在很清楚了;即使您隐藏sidebar(内部的形式),仍然会有div包围它。

所以我们希望隐藏div。不幸的是,我找不到使用sidebarPanel函数的方法。另一种方法是使用column函数。

column(width=3, id="col", actionButton("b", "btn"))
##<div class="col-sm-3" id="col">
##  <button id="b" type="button" class="btn btn-default action-button">btn</button>
##</div>

您可以看到column的输出类似于sidebarPanel的输出。重要的是,column允许您为div元素提供ID。

所以,这是一个玩具示例,将主面板向左移动(即完全隐藏侧边栏)。

library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
  column(width=4, id="spcol", actionButton("dummy", "dummy")),
  column(width=8, wellPanel(actionButton("sideBarControl", 
                                         label = "Show/Hide")))
)))

server <- function(input, output) {
  observeEvent(input$sideBarControl, {
    shinyjs::toggle(id = "spcol")
  })
}
shinyApp(ui = ui, server = server)

现在,让我们解决你的第二点,即让主面板填满,而不是转移。

mainPanel()
##<div class="col-sm-8"></div>

因此它没有填充,因为它的宽度设置为8.我们想将其更改为12,我们可以使用toggleClass库中的shinyjs函数。简而言之,如果元素没有一个类,toggleClass会向它添加一个类,如果它已经存在,则删除该类。
我相信下面的代码符合我们的意愿。

library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
  column(width=4, id="spcol", actionButton("dummy", "dummy")),
  column(width=8, id="main", wellPanel(actionButton("sideBarControl", 
                                                     label = "Show/Hide")))
)))

server <- function(input, output) {
  observeEvent(input$sideBarControl, {
    shinyjs::toggle(id = "spcol")
    shinyjs::toggleClass("main", "col-sm-8")
    shinyjs::toggleClass("main", "col-sm-12")
  })
}
shinyApp(ui = ui, server = server)

此外,这是另一个工作示例代码,其中隐藏了两个不同宽度的主面板版本,并依次显示。

library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
  column(width=4, id="spcol", actionButton("dummy", "dummy")),
  column(width=8, id="main1", wellPanel(actionButton("sideBarControl", 
                                        label = "Show/Hide"))),
  column(width=12, id="main2", wellPanel(actionButton("sideBarControl2", 
                                        label = "Show/Hide")))
)))

server <- function(input, output) {
  shinyjs::toggle(id = "main2")

  observeEvent(input$sideBarControl+input$sideBarControl2, {
    shinyjs::toggle(id = "spcol")
    shinyjs::toggle(id = "main1")
    shinyjs::toggle(id = "main2")
  })
}
shinyApp(ui = ui, server = server)

答案 1 :(得分:0)

你试试shinydashboard怎么样?它具有您默认寻找的行为。

https://rstudio.github.io/shinydashboard/get_started.html