I have the below proto-type of my shiny app with two pages and two selectInput
buttons in each page.
ui <- dashboardPage(
dashboardHeader(title = "Header",
dropdownMenuOutput("updatedTimeOutput"),
dropdownMenu(type = "notifications",
badgeStatus = "warning",
icon = icon("bullhorn", "fa-lg"),
notificationItem(icon = icon("bullhorn", "fa-1x"),
status = "info",
text = tags$span(
tags$b("Please notice!")
)
))),
dashboardSidebar( sidebarMenu(id = "tabs",
menuItem("Page1", tabName = "page1"),
menuItem("Page2", tabName = "page2"))),
dashboardBody(
tabItems(
tabItem(
tabName = "page1",
fluidRow(column(2,
selectInput("count1", "Select a category", c("1", "2"))),
column(2,selectInput("count2", "Select a subcategory1",
c("cat1", "cat2", "cat3", "cat4")))),
fluidRow(infoBoxOutput("ibox1")),
fluidRow(valueBoxOutput("vbox1"))
)
,
tabItem(
tabName = "page2",
fluidRow(column(2,
selectInput("count3", "Select a category", c("1", "2"))),
column(2, selectInput("count4", "Select a subcategory2",
c("sub1", "sub2", "sub3", "sub4")))),
fluidRow(infoBoxOutput("ibox2")),
fluidRow(valueBoxOutput("vbox2")
)
)
)
)
)
server <- function(input, output) {
output$ibox1 <- renderInfoBox({
infoBox(
"Title",
input$count1,
icon = icon("credit-card")
)
})
output$vbox1 <- renderValueBox({
valueBox(
"Title",
input$count2,
icon = icon("credit-card")
)
})
output$ibox2 <- renderInfoBox({
infoBox(
"Title",
input$count3,
icon = icon("credit-card")
)
})
output$vbox2 <- renderValueBox({
valueBox(
"Title",
input$count4,
icon = icon("credit-card")
)
})
}
shinyApp(ui, server)
If the app is run, we will see two selectInput
buttons in the body of each page. Is it possible to move the selectInput
buttons in each page to the header so that it looks like:
page 1:
page 2:
The inputButtons should be placed in the header and should show the corresponding inputs of each page. Can someone help if it could be done in shiny application making use of any custom CSS or javascript or html?
Try these CSS tricks, mobile friendly.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Header"),
dashboardSidebar( sidebarMenu(id = "tabs",
menuItem("Page1", tabName = "page1"),
menuItem("Page2", tabName = "page2"))),
dashboardBody(
tabItems(
tabItem(
tabName = "page1",
fluidRow(class = "select-to-top", column(2,
selectInput("count1", "Select a category", c("1", "2"))),
column(2,selectInput("count2", "Select a subcategory1",
c("cat1", "cat2", "cat3", "cat4")))),
fluidRow(infoBoxOutput("ibox1")),
fluidRow(valueBoxOutput("vbox1"))
)
,
tabItem(
tabName = "page2",
fluidRow(class = "select-to-top", column(2,
selectInput("count3", "Select a category", c("1", "2"))),
column(2, selectInput("count4", "Select a subcategory2",
c("sub1", "sub2", "sub3", "sub4")))),
fluidRow(infoBoxOutput("ibox2")),
fluidRow(valueBoxOutput("vbox2")
)
)
),
tags$style(HTML(
"@media (min-width: 767px) {
.select-to-top {
position: fixed;
top: 0;
left: 49%;
width: 1000px;
z-index: 9999;
}
.main-header .logo {
height: 80px;
}
.left-side, .main-sidebar {
padding-top: 80px;
}
}
"
))
)
)
server <- function(input, output) {
output$ibox1 <- renderInfoBox({
infoBox(
"Title",
input$count1,
icon = icon("credit-card")
)
})
output$vbox1 <- renderValueBox({
valueBox(
"Title",
input$count2,
icon = icon("credit-card")
)
})
output$ibox2 <- renderInfoBox({
infoBox(
"Title",
input$count3,
icon = icon("credit-card")
)
})
output$vbox2 <- renderValueBox({
valueBox(
"Title",
input$count4,
icon = icon("credit-card")
)
})
}
shinyApp(ui, server)
We fixed the header as well. When you scroll, the entire header is fixed on top. Change style to this
tags$style(HTML(
"@media (min-width: 767px) {
.select-to-top {
position: fixed;
top: 0;
left: 49%;
width: 1000px;
z-index: 9999;
}
.main-header .logo {
height: 80px;
position: fixed;
}
.navbar.navbar-static-top {
position: fixed;
height: 80px;
width: 100%;
}
.left-side, .main-sidebar {
padding-top: 80px;
}
.content-wrapper {
padding-top: 80px;
}
}
"
))
Both input and header stay on top and don't move.
Use this style, just changed the position
tags$style(HTML(
"@media (min-width: 767px) {
.select-to-top {
position: absolute;
top: 0;
left: 49%;
width: 1000px;
z-index: 9999;
}
.main-header .logo {
height: 80px;
}
.left-side, .main-sidebar {
padding-top: 80px;
}
}
"
))
This code should make you work with dropdown menus.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Header", dropdownMenu(type = "messages",
messageItem(from = "Sales Dept",message = "Sales are steady this month."))),
dashboardSidebar( sidebarMenu(id = "tabs",
menuItem("Page1", tabName = "page1"),
menuItem("Page2", tabName = "page2"))),
dashboardBody(
tabItems(
tabItem(
tabName = "page1",
fluidRow(class = "select-to-top",
column(6, selectInput("count1", "Select a category", c("1", "2"))),
column(6,selectInput("count2", "Select a subcategory1", c("cat1", "cat2", "cat3", "cat4")))
),
fluidRow(infoBoxOutput("ibox1")),
fluidRow(valueBoxOutput("vbox1")),
lapply(1:40, br)
),
tabItem(
tabName = "page2",
fluidRow(class = "select-to-top",
column(6,selectInput("count3", "Select a category", c("1", "2"))),
column(6, selectInput("count4", "Select a subcategory2", c("sub1", "sub2", "sub3", "sub4")))
),
fluidRow(infoBoxOutput("ibox2")),
fluidRow(valueBoxOutput("vbox2")
)
)
),
tags$style(HTML(
"@media (min-width: 767px) {
.select-to-top {
position: absolute;
top: 0;
left: 50%;
color: white;
transform: translateX(-45%);
width: 500px;
z-index: 9999;
}
.main-header .logo {
height: 60px;
}
.left-side, .main-sidebar {
padding-top: 60px;
}
}
"
))
)
)
server <- function(input, output) {
output$ibox1 <- renderInfoBox({
infoBox(
"Title",
input$count1,
icon = icon("credit-card")
)
})
output$vbox1 <- renderValueBox({
valueBox(
"Title",
input$count2,
icon = icon("credit-card")
)
})
output$ibox2 <- renderInfoBox({
infoBox(
"Title",
input$count3,
icon = icon("credit-card")
)
})
output$vbox2 <- renderValueBox({
valueBox(
"Title",
input$count4,
icon = icon("credit-card")
)
})
}
shinyApp(ui, server)