点击左侧工具栏菜单项上的“激活/停用”功能,然后点击左侧面板菜单项

时间:2019-09-19 13:45:16

标签: r shiny shinydashboard shinyjs

我正在使用出色的ShinyDashoardPlus包(以Dashboardthemes包中的主题为样式)构建一个Shiny应用程序,其中包含三个tabItems,其中包含三个部分的内容应用程序(A节,B节和C节),可通过左侧sidebarMenu中的dashboardSidebar和带有两个选项卡的右侧边栏(实现为rightSidebarTabContent,具有以下ID)进行访问: T_AT_B)按住控件分别分别探索A和B部分的内容。

由于rightSidebarTabContent T_A仅与section A相关,而rightSidebarTabContent T_B仅与section B相关,我想(1)用户点击左侧工具栏上的菜单项A或B 可以激活右侧工具栏中的相应标签。此外,由于rightSidebarTabContents中的section C都不相关,因此我也希望(2)用户点击左侧边栏菜单项C 上的<如果已打开,则strong>关闭右侧栏。

我发现了有关如何解决问题的可能提示(Automatic rightSidebar popup when menuItem is clicked in shinydashboardPlus),并且确实能够部分解决我的第一个问题,即通过shinyjs添加/删除一些CSS类来激活点击rightSidebar时,menuItems中不同标签的一部分。

正如我所说,该解决方案部分适用于我的第一个问题,尽管只有rightSidebarTabContent下部是通过这种方式激活/停用的,但选项卡页眉中没有用于在它们之间导航的图标。此外,可能是由于应用我的闪亮仪表板主题“黑暗”时添加了额外的CSS类,因此无法单击rightSidebar菜单项(issue#2)来切换section C的关闭状态。

总结:

  1. 选择了左侧边栏项目T_A时,右侧边栏项目section A应该会展开。对于T_Asection B也是如此。
  2. 在左侧栏上选择section C时,右侧栏应折叠

有人可以帮忙吗?预先感谢您的帮助!

library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinydashboard)
library(shinydashboardPlus)
library(dashboardthemes)

ui <- dashboardPagePlus(
  useShinyjs(),
  header = dashboardHeaderPlus(
    title = "Dashboard",
    enable_rightsidebar = TRUE,
    rightSidebarIcon = "info-circle"
  ),
  sidebar = dashboardSidebar(
    sidebarMenu(
      menuItem("Section A", tabName = "Section_A", icon = icon("map")),
      menuItem("Section B", tabName = "Section_B", icon = icon("chart-line")),
      menuItem("Section C", tabName = "Section_C", icon = icon( "gears")),
      id = "nav"
    )
  ),
  body = dashboardBody(
    shinyDashboardThemes(
      theme = "grey_dark"
    ),
    tabItems(
      tabItem(
        tabName = "Section_A",
        p("Some content for section A")),
      tabItem(
        tabName = "Section_B",
        p("Some content for section B")),
      tabItem(
        tabName = "Section_C",
        p("Some content for section C"))
      )
  ),
  rightsidebar = rightSidebar(
    background = "dark",
    rightSidebarTabContent(
      id = "T_A",
      title = "Tab for section A",
      icon = "desktop",
      active = TRUE,
      p("Some content frelevant for section A"),
      sliderInput(
        "obs",
        "Number of observations:",
        min = 0, max = 1000, value = 500
      )
    ),
    rightSidebarTabContent(
      id = "T_B",
      title = "Tab for section B",
      p("Some content frelevant for section B"),
      textInput("caption", "Caption", "Data Summary")
    )
  ),
  title = "Right Sidebar"
)


server <- function(input, output) {
  observe({
    if (req(input$nav) == "Section_A"){
      message("Section A has been selected")
      shinyjs::removeClass(id = "control-sidebar-T_A-tab", class = "tab-pane")
      shinyjs::removeClass(id = "control-sidebar-T_B-tab", class = "tab-pane active")
      shinyjs::addClass(id = "control-sidebar-T_A-tab", class = "tab-pane active")
      shinyjs::addClass(id = "control-sidebar-T_B-tab", class = "tab-pane")
    }
    if (req(input$nav) == "Section_B"){
      message("Section B has been selected")
      shinyjs::removeClass(id = "control-sidebar-T_B-tab", class = "tab-pane")
      shinyjs::removeClass(id = "control-sidebar-T_A-tab", class = "tab-pane active")
      shinyjs::addClass(id = "control-sidebar-T_B-tab", class = "tab-pane active")
      shinyjs::addClass(id = "control-sidebar-T_A-tab", class = "tab-pane")
    }
    if (req(input$nav) == "Section_C"){
      message("Section C has been selected")
      shinyjs::removeClass(selector = "aside.control-sidebar-open aside.control-sidebar-dark", class = "control-sidebar-open aside.control-sidebar-dark-open")
      shinyjs::addClass(selector = "aside.control-sidebar", class = "control-sidebar")
    }
  })
}


shinyApp(ui = ui, server = server)

3 个答案:

答案 0 :(得分:1)

您可以通过renderUI反应性地渲染右侧边栏项目,而不用修改CSS。在rightSidebar内,我们可以放置一个uiOutput,其中将填充不同的内容,具体取决于左侧边栏中的所选项目。请注意,这是部分解决方案。边栏一旦展开,在左侧边栏中选择section C时仍不会折叠。 [请参阅下面的修改,该修改解决了右侧栏的折叠。]

library(shinyjs)
library(shinyWidgets)
library(shinydashboard)
library(shinydashboardPlus)
library(dashboardthemes)

ui <- dashboardPagePlus(
  useShinyjs(),
  header = dashboardHeaderPlus(
    title = "Dashboard",
    enable_rightsidebar = TRUE,
    rightSidebarIcon = "info-circle"
  ),
  sidebar = dashboardSidebar(
    sidebarMenu(
      menuItem("Section A", tabName = "Section_A", icon = icon("map")),
      menuItem("Section B", tabName = "Section_B", icon = icon("chart-line")),
      menuItem("Section C", tabName = "Section_C", icon = icon( "gears")),
      id = "nav"
    )
  ),
  body = dashboardBody(
    shinyDashboardThemes(
      theme = "grey_dark"
    ),
    tabItems(
      tabItem(
        tabName = "Section_A",
        p("Some content for section A")),
      tabItem(
        tabName = "Section_B",
        p("Some content for section B")),
      tabItem(
        tabName = "Section_C",
        p("Some content for section C"))
    )
  ),
  rightsidebar = rightSidebar(
    background = "dark",
    uiOutput("side_bar"),
    title = "Right Sidebar"
  )
)

server <- function(input, output) {
  observe({
    if (req(input$nav) == "Section_A"){
      message("Section A has been selected")
      # added in edit
      shinyjs::addClass(selector = "aside.control-sidebar", class = "control-sidebar-open")
      output$side_bar <- renderUI({
        rightSidebarTabContent(
          id = "T_A",
          title = "Tab for section A",
          p("Some content relevant for section A"),
          sliderInput(
            "obs",
            "Number of observations:",
            min = 0, max = 1000, value = 500
          )
        )
      })
    }
    if (req(input$nav) == "Section_B"){
      message("Section B has been selected")
      # added in edit
      shinyjs::addClass(selector = "aside.control-sidebar", class = "control-sidebar-open")
      output$side_bar <- renderUI({
        rightSidebarTabContent(
          id = "T_B",
          title = "Tab for section B",
          p("Some content relevant for section B"),
          textInput("caption", "Caption", "Data Summary")
        )
      })
    }

    if (req(input$nav) == "Section_C"){
      message("Section C has been selected")
      # added in edit
      shinyjs::removeClass(selector = "aside.control-sidebar", class = "control-sidebar-open")

      output$side_bar <- renderUI({ div() })
    }
  })
}


shinyApp(ui = ui, server = server)

编辑:单击section C时会折叠右侧边栏。阅读您更仔细地链接的帖子后,您只需添加

shinyjs::addClass(selector = "aside.control-sidebar", class = "control-sidebar-open")

在观察者中选择section Asection B并添加

shinyjs::removeClass(selector = "aside.control-sidebar", class = "control-sidebar-open")

当选择section C时。

然后,右侧边栏将根据左侧边栏中的选择展开和折叠。

行为的gif:

enter image description here

答案 1 :(得分:1)

除了teofil的答案外,您还可以使用选择器=“ body”,这样右侧边栏仍然可以打开和关闭。

shinyjs::addClass(selector = "body", class = "control-sidebar-open")
shinyjs::removeClass(selector = "body", class = "control-sidebar-open")

答案 2 :(得分:1)

另一种解决方案是使用shiny::tabsetPanel代替shinydashboardPlus::rightSidebarTabContent

要在右侧边栏中使用tabsetPanel,但仍看起来像Shinydashboard的右侧边标签集面板,则需要一些CSS样式,包括removing the dark space at the top of the right sidebar panelchanging the 'active' and 'hover' colours of the tabpanel

显示/隐藏tabPanel仅需要使用showTabhideTab。可以使用select的{​​{1}}参数来选择选项卡,而不必隐藏其他选项卡。

作为奖励,我还添加了一个showTab演练。如代码所示,演练过程中面板的更改无法“看到”,但这正在发生!

感谢CPB的回答,它显示了显示/隐藏右侧边栏的最佳方法。

rintrojs