根据输入参数切换 shinydashboard menuItems

Toggle shinydashboard menuItems based on input parameters

我正在构建一个大型 shinydashboard 应用程序,它可以获取两种数据,monthlyinterval。从下拉列表中选择"Monthly"时,应显示一些选项卡,并在选择"Interval"时隐藏(反之亦然)。

我尝试将两个 类、"OnlyMonthly" 和 "OnlyInterval," 分配给相关的 menuItem(),方法是将它们包装在 div() 标签中,然后使用 shinyJStoggle() 命令在选择 "Monthly" 时显示“.OnlyMonthly”并隐藏“.OnlyInterval”,但菜单的格式受到影响并且不起作用。

这是基本应用程序的代码:

require(shiny)
require(shinydashboard)
require(shinyjs)

ui <- dashboardPage(
  header = dashboardHeader(title = 'Toggle Menu'),
  sidebar = dashboardSidebar(
    sidebarMenu(
      menuItem('Item 1', tabName = 'item1',
        menuSubItem('Item A', tabName = 'item1A'),
        # just hide Item B
        div(menuSubItem('Item B', tabName = 'item1B'), class = 'OnlyMonthly')
      ),

      # hide all of Item 2, including C and D
      div(class = 'OnlyInterval',
        menuItem('Item 2', tabName = 'item2',
          menuSubItem('Item C', tabName = 'item2C'),
          menuSubItem('Item D', tabName = 'item2D')
        )
      )

    )
  ),
  body = dashboardBody(
    useShinyjs(),
    selectInput(inputId = 'monthly_vs_interval', label = 'Data type',choices = c('Monthly','Interval'))
  )
)

server <- shinyServer(function(input, output, session) {
  observe({
    toggle(selector = ".OnlyMonthly", input$monthly_vs_interval == 'Monthly')
    toggle(selector = ".OnlyInterval", input$monthly_vs_interval == 'Interval')
  })
})

shinyApp(ui = ui, server = server)

经过测试,我发现 conditionalPanel 正确 shows/hides 标签,但格式仍然受到影响。似乎 sidebarMenu 只允许 menuItem 作为孩子,menuItemmenuSubItem 也是如此。您可能可以通过 id 隐藏 menuItem(请参阅 ?menuItem),但可能无法在不影响格式的情况下 show/hide menuSubItems。

require(shiny)
require(shinydashboard)

ui <- dashboardPage(
  header = dashboardHeader(title = 'Toggle Menu'),
  sidebar = dashboardSidebar(
    sidebarMenu(
      menuItem('Item 1', tabName = 'item1',
               menuSubItem('Item A', tabName = 'item1A'),
               # just hide Item B
               conditionalPanel(menuSubItem('Item B', tabName = 'item1B'), 
                                condition = "input.monthly_vs_interval == 'Monthly'")
      ),

      # hide all of Item 2, including C and D
      conditionalPanel(condition = "input.monthly_vs_interval == 'Interval'",
          menuItem('Item 2', tabName = 'item2',
                   menuSubItem('Item C', tabName = 'item2C'),
                   menuSubItem('Item D', tabName = 'item2D')
          )
      )

    )
  ),
  body = dashboardBody(
    selectInput(inputId = 'monthly_vs_interval', label = 'Data type',
                choices = c('Monthly', 'Interval'))
  )
)

server <- function(...){}

shinyApp(ui = ui, server = server)

编辑:实际上,只有sidebarMenu有一个id参数。在 menuSubItem 中使用名为 id 的参数会导致语法错误,而在 menuItem 中通过 id 使用 show/hide 会导致意外结果。我想您总是可以通过在 sidebarMenu 之外使用 conditionalPanel 以 "dirty" 的方式对其进行编码。但是请注意,这种方法有点像 WET.

require(shiny)
require(shinydashboard)

ui <- dashboardPage(
  header = dashboardHeader(title = 'Toggle Menu'),
  sidebar = dashboardSidebar(
    conditionalPanel(
      condition = "input.monthly_vs_interval == 'Monthly'",
      sidebarMenu(menuItem(
        'Item 1', tabName = 'item1',
        menuSubItem('Item A', tabName = 'item1A'),
        menuSubItem('Item B', tabName = 'item1B')
      ))
    ),
    conditionalPanel(
      condition = "input.monthly_vs_interval == 'Interval'",
      sidebarMenu(
        menuItem('Item 1', tabName = 'item1',
                 menuSubItem('Item A', tabName = 'item1A')
        ),
        menuItem('Item 2', tabName = 'item2',
                 menuSubItem('Item C', tabName = 'item2C'),
                 menuSubItem('Item D', tabName = 'item2D')
        )
      )
    )
  ),
  body = dashboardBody(
    selectInput(inputId = 'monthly_vs_interval', label = 'Data type',
                choices = c('Monthly', 'Interval'))
  )
)

server <- function(...){}

shinyApp(ui = ui, server = server)