Closed phillc73 closed 9 years ago
After a bit more digging around - I tried sidebar menuItems with datatable content in the body, rather than box() content - I think the issue is not so much the content disappearing, but rather the tabItem is not being loaded. This was not obvious with just one tabItem. However, if adding a second tabItem, and the corresponding menuItem contains input widgets, the tabItem will not load.
Here's some example code:
library("shinydashboard")
header <- dashboardHeader()
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Inputs One", icon = icon("bar-chart-o"), tabName = "tabOne"),
menuItem("Inputs Two", icon = icon("line-chart"), tabName = "tabTwo",
# Input directly under menuItem
selectInput("inputTest", "Input Test",
choices = c("a", "b", "c", "d"), multiple=TRUE, selectize=TRUE,
width = '98%'),
# Input inside of menuSubItem
menuSubItem(icon = NULL,
sliderInput("inputTest2", "Input test 2", min=0, max=10, value=5,
width = '95%')
)
)
)
)
body <- dashboardBody(
tabItems(
tabItem("tabOne",
box(title = "Box One",
width = 12,
height = "500px",
status = "success",
solidHeader = TRUE,
collapsible = TRUE,
verbatimTextOutput("boxOneText")
)
),
tabItem("tabTwo",
box(title = "Box Two",
width = 12,
height = "500px",
status = "success",
solidHeader = TRUE,
collapsible = TRUE,
verbatimTextOutput("boxTwoText")
)
)
)
)
shinyApp(
ui = dashboardPage(header, sidebar, body),
server = function(input, output) {
output$boxOneText <- renderText({
paste("A test designed to provoke an emotional response")
})
output$boxTwoText <- renderText({
paste("Nothing is worse than having an itch you can never scratch.")
})
}
)
Thanks for the example code - it's very helpful for tracking down the issue.
The root of the problem is that any menuItem
that has child elements, like menuSubItem
s or shiny inputs, can't be used to control tabItem
s. It's a little confusing because with AdminLTE 2.x, the menuItem
will be highlighted (and expand) when you click on it, but I believe that with AdminLTE 1.x, it was different -- the item would only expand, and not be highlighted.
I'm not sure that it makes sense to allow a menu item to both expand and control tabs, since it makes for some confusing interactions. Right now, it's pretty simple: an expandable menu item can only expand.
Say you have two menu items, X and Y, where just Y has sub-items. Also, they have corresponding tabNames, Xtab and Ytab. Imagine the following:
The trouble is that expanding/collapsing is a toggle sort of event, whereas selecting a tab and making its content visible is an idempotent sort of event. And making one menuItem do both tasks doesn't quite seem right.
If, however, you have thoughts a way to make it work, and make sense, let me know.
I can see how it currently could be confusing.
My use case is that certain inputs, or filters, only apply to certain tab content. To save space within dashboardPage, I'd much rather locate the filters in the sidebar. Xtab shows a table. I want to filter this table using a selectInput
widget. This widget only applies to the table content in Xtab and therefore could happily live in the X menuItem
sidebar. This is a direct extension of how I'd write a Shiny app without shinydashboard. I really like the added features of shinydashboard, but it feels like a small step backwards to force inputs into dashboardPage, when there are multiple menuItem
s.
(As an aside, global inputs/filters in the dashboardHeader would also be nice!)
Working through your scenarios:
menuItem
to collapse unless another menuItem
was selected? Y would never collapse until X was selected. I think this makes logical sense and can't specifically think of a reason why one would want Y collapsed, without moving to another menuItem
menuItem
can be expanded at any one time.The key thing is to only allow one menuItem
to expand at any one time.
I'm in the same situation, where I have a number of menuItem
s each of which should display a different tab and each having their own set of controls. Ideally the tab choice would be triggered when I click on the menuItem
.
I agree with @phillc73 in that it's a small step backwards to force inputs into dashboardPage.
My workaround at the moment is to a (superfluous) menuSubItem in each menu item that then needs to be clicked to trigger the tab:
menuItem(text="Tab 1",
menuSubItem("Show tab",tabName = "tab1", selected=TRUE),
# controls here
),
menuItem(text="Tab2",
menuSubItem("Show tab",tabName = "tab2", selected=FALSE),
# controls here
)
This is OK, but not ideal because it requires two clicks to get the plot displayed. Perhaps an invisible menuSubItem
could be implemented that can (optionally) be added to the menuItem
(as above) but is triggered automatically when the menuItem
is displayed?
I just realized it should be possible to use conditionalPanel
s to get the desired effect. Here's an example (this requires the latest dev version of shinydashboard):
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(id = "sidebarmenu",
menuItem("A", tabName = "a", icon = icon("group", lib="font-awesome")),
menuItem("B", tabName = "b", icon = icon("check-circle", lib = "font-awesome")),
conditionalPanel("input.sidebarmenu === 'b'",
sliderInput("b", "Under sidebarMenu", 1, 100, 50)
)
),
sliderInput("x", "Outside of menu", 1, 100, 50)
),
dashboardBody()
)
server <- function(input, output) {}
shinyApp(ui, server)
I have a feeling that other potential solutions would require too much modification of the AdminLTE code and lead to maintenance problems in the future.
Thanks for the update @wch, that's a close enough approximation for my purposes. Any idea when the latest dev version will be pushed to CRAN?
@garthtarr Great, glad that works for you. I'm going to be out for a little while, so it'll probably be a couple of weeks before the new version goes to CRAN.
thanks, garthtarr.
Thank you @phillc73 and @garthtarr, nice work around, though the second click is not as intuitive
If using widgets as nested menu or sub-menu items, content in the dashboardBody fails to render.
Examples
This displays the box in dashboardBody() correctly:
However, the following code with correctly displaying widget inputs added as menu items, results in the dashboardBody() box disappearing.