tab specific sidebar in shinydashboard

倾然丶 夕夏残阳落幕 提交于 2019-12-24 16:18:19

问题


I am using the shinyjs package in R to allow for onclick type events to navigate between tabs in a tabset. Each tab has a specific sidebar, and there are multiple (two) ways of getting between each tab (i.e. via clicking on the tab itself or by clicking on the valueBoxes). I would like to ensure that no matter what way you get to a specific tab the correct sidebar loads.

# load libraries
require(shiny)
require(shinydashboard)
require(shinyjs)

# create a simple app
ui <- dashboardPage(
  title='Loading graphs',
  dashboardHeader(
    title = 'Loading Graphs'
  ),
  dashboardSidebar(
    div(id='tab1_sidebar',
        sliderInput('tab1_slider', 'tab1 slider', min=2,max=7,value=2)),
    shinyjs::hidden(
      div(id='tab2_sidebar',
          sliderInput('tab2_slider', 'tab2 slider', min=2,max=7,value=2))
      )
  ),
  dashboardBody(
    useShinyjs(),
    tabsetPanel(
      id = "navbar",
      tabPanel(title="tab1 title",id="tab1",value='tab1_val',
               valueBoxOutput('tab1_valuebox')),
      tabPanel(title="tab2 title",id="tab2",value='tab2_val',
               valueBoxOutput('tab2_valuebox'))
    )
  )
)

server <- shinyServer(function(input, output, session) {

  output$tab1_valuebox <- renderValueBox({
    valueBox('1000',subtitle = "blah blah",icon = icon("car"),
             color = "blue"
    )
  })

  output$tab2_valuebox <- renderValueBox({
    valueBox('2000',subtitle = "blah2 blah2",icon = icon("car"),
             color = "red"
    )
  })



  # on click of a tab1 valuebox
  shinyjs::onclick('tab1_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab2_val')
    # update the sidebar to match the tab
    toggle('tab1_sidebar')
    toggle('tab2_sidebar')
  })

  # on click of a tab2 valuebox
  shinyjs::onclick('tab2_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab1_val')
    # update the sidebar to match the tab
    toggle('tab1_sidebar')
    toggle('tab2_sidebar')
  })
})

shinyApp(ui=ui,server=server)

In the code above, when clicking on the tab the sidebar does not change, but if I include the below code into the server component to take allow for clicking on the tab it doesn't seem to adjust correctly...

# change sidebar based on navbar value....
observeEvent(input$navbar,{
  if(input$navbar=='tab1_val'){
      toggle('tab1_sidebar')
      toggle('tab2_sidebar')
  } else if(input$navbar=='tab2_val'){
      toggle('tab1_sidebar')
      toggle('tab2_sidebar')
  }
})

Any help on this would be much appreciated....


回答1:


Right now it doesn't look like you have any logic in your code that tells the slider to update when you switch tabs, only when the valueBox is clicked.

There are different approaches you can go about this.

Option 1: listening when the navbar changes and using toggle() with a condition

This is very similar to your code, but instead of calling the toggle() function whenever there is a click, all I do onclick is change the selected tab. When the tab value changes (either by clicking on a valueBox or by clicking on a tab), then call the toggle() function. Small but important difference.

# load libraries
require(shiny)
require(shinydashboard)
require(shinyjs)

# create a simple app
ui <- dashboardPage(
  title='Loading graphs',
  dashboardHeader(
    title = 'Loading Graphs'
  ),
  dashboardSidebar(
    div(id='tab1_sidebar',
        sliderInput('tab1_slider', 'tab1 slider', min=2,max=7,value=2)),
    shinyjs::hidden(
      div(id='tab2_sidebar',
          sliderInput('tab2_slider', 'tab2 slider', min=2,max=7,value=2))
    )
  ),
  dashboardBody(
    useShinyjs(),
    tabsetPanel(
      id = "navbar",
      tabPanel(title="tab1 title",id="tab1",value='tab1_val',
               valueBoxOutput('tab1_valuebox')),
      tabPanel(title="tab2 title",id="tab2",value='tab2_val',
               valueBoxOutput('tab2_valuebox'))
    )
  )
)

server <- shinyServer(function(input, output, session) {

  values <- reactiveValues(selectedTab = 1)

  observeEvent(input$navbar, {
    toggle("tab1_sidebar", condition = input$navbar == "tab1_val")
    toggle("tab2_sidebar", condition = input$navbar == "tab2_val")
  })

  output$tab1_valuebox <- renderValueBox({
    valueBox('1000',subtitle = "blah blah",icon = icon("car"),
             color = "blue"
    )
  })

  output$tab2_valuebox <- renderValueBox({
    valueBox('2000',subtitle = "blah2 blah2",icon = icon("car"),
             color = "red"
    )
  })



  # on click of a tab1 valuebox
  shinyjs::onclick('tab1_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab2_val')
  })

  # on click of a tab2 valuebox
  shinyjs::onclick('tab2_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab1_val')
  })
})

shinyApp(ui=ui,server=server)

Option 2: using conditionalPanel()

As the author of shinyjs I love the toggle function, but in this case it's not absolutely necessary, you could get away with just using conditionalPanel(). Here's the code I think you want:

# load libraries
require(shiny)
require(shinydashboard)
require(shinyjs)

# create a simple app
ui <- dashboardPage(
  title='Loading graphs',
  dashboardHeader(
    title = 'Loading Graphs'
  ),
  dashboardSidebar(
    conditionalPanel("input.navbar == 'tab1_val'",
      div(id='tab1_sidebar',
          sliderInput('tab1_slider', 'tab1 slider', min=2,max=7,value=2))
    ),
    conditionalPanel("input.navbar == 'tab2_val'",
      div(id='tab2_sidebar',
          sliderInput('tab2_slider', 'tab2 slider', min=2,max=7,value=2))
    )
  ),
  dashboardBody(
    useShinyjs(),
    tabsetPanel(
      id = "navbar",
      tabPanel(title="tab1 title",id="tab1",value='tab1_val',
               valueBoxOutput('tab1_valuebox')),
      tabPanel(title="tab2 title",id="tab2",value='tab2_val',
               valueBoxOutput('tab2_valuebox'))
    )
  )
)

server <- shinyServer(function(input, output, session) {

  output$tab1_valuebox <- renderValueBox({
    valueBox('1000',subtitle = "blah blah",icon = icon("car"),
             color = "blue"
    )
  })

  output$tab2_valuebox <- renderValueBox({
    valueBox('2000',subtitle = "blah2 blah2",icon = icon("car"),
             color = "red"
    )
  })



  # on click of a tab1 valuebox
  shinyjs::onclick('tab1_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab2_val')
  })

  # on click of a tab2 valuebox
  shinyjs::onclick('tab2_valuebox',expr={
    # move to tab2
    updateTabsetPanel(session, "navbar", 'tab1_val')
  })
})

shinyApp(ui=ui,server=server)


来源:https://stackoverflow.com/questions/38488174/tab-specific-sidebar-in-shinydashboard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!