I was making reactive shiny web page and stucked at the code below.
library(shiny)
library(shinydashboard)
ui = dashboardPage(
dashboardHeader(title = "header"),
dashboardSidebar(
sidebarMenuOutput("sideBar")),
dashboardBody(
uiOutput("test")
)
)
server = shinyServer(function(input, output, session) {
output$sideBar <- renderMenu({
sidebarMenu(id = "menu",
menuItem("Dashboard", tabName ="dashboard", icon = icon('dashboard')),
menuItem("DBcentor", tabName ="dbcenter", icon = icon('database'))
)
})
output$test <- renderUI ({
tabItems(
tabItem(tabName = "dashboard", uiOutput("dashboardbody")),
tabItem(tabName = "dbcenter", uiOutput("dbcenterbody"))
)
})
output$dashboardbody <- renderUI ({
box("Dashboard Body")
})
output$dbcenterbody <- renderUI ({
box("Dbcenter Body")
})
})
shinyApp(ui, server)
I used uiOutput to build body but after shiny app is loaded, nothing comes out at the dashboard page.
I changed my code like this,
library(shiny)
library(shinydashboard)
ui = dashboardPage(
dashboardHeader(title = "header"),
dashboardSidebar(
sidebarMenuOutput("sideBar")),
dashboardBody(
tabItems(
tabItem(tabName = "dashboard", uiOutput("dashboardbody")),
tabItem(tabName = "dbcenter", uiOutput("dbcenterbody"))
)
)
)
server = shinyServer(function(input, output, session) {
output$sideBar <- renderMenu({
sidebarMenu(id = "menu",
menuItem("Dashboard", tabName ="dashboard", icon = icon('dashboard')),
menuItem("DBcentor", tabName ="dbcenter", icon = icon('database'))
)
})
output$dashboardbody <- renderUI ({
box("Dashboard Body")
})
output$dbcenterbody <- renderUI ({
box("Dbcenter Body")
})
})
shinyApp(ui, server)
Of course it works and box("dashboadbody") comes out at the first page.
I want to use uiOutput because i should use input data to build menus and items.
Any ways to use uiOutput and get box("dashboard") on the default page at the same time?
Try this
ui = dashboardPage(
dashboardHeader(title = "header"),
dashboardSidebar(
sidebarMenuOutput("sideBar")),
dashboardBody(
uiOutput("test")
)
)
server = shinyServer(function(input, output, session) {
output$sideBar <- renderMenu({
sidebarMenu(id = "menu",
menuItem("Dashboard", tabName ="dashboard", icon = icon('dashboard')),
menuItem("DBcentor", tabName ="dbcenter", icon = icon('database'))
)
})
output$dashboardbody <- renderUI ({
box("Dashboard Body")
})
output$dbcenterbody <- renderUI ({
box("Dbcenter Body")
})
updateTabItems(session,"menu","dbcenter")
updateTabItems(session,"menu","dashboard")
output$test <- renderUI ({
tagList(
tabItems(
tabItem(tabName = "dashboard", uiOutput("dashboardbody")),
tabItem(tabName = "dbcenter", uiOutput("dbcenterbody"))
))
})
})
shinyApp(ui, server)
Related
I cannot use updateTabItems() on a menuSubItem created by renderMenu() when I click on actionButton().
To illustrate my problem, here is an example code and a video (end of the post):
library(shiny)
library(DT)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("First item", "first_item",
actionButton("action_button", "Action"),
menuSubItem("First sub item", "first_sub_item")
),
menuItem("Second item", "second_item",
menuItemOutput("second_sub_item")
)
)
),
dashboardBody(
tabItems(
tabItem("first_sub_item",
DT::dataTableOutput("df")
),
tabItem("second_sub_item",
verbatimTextOutput('row_selected')
)
)
)
)
server <- function(input, output, session){
observeEvent(input$action_button, {
output$df <- DT::renderDataTable(
as.data.frame(replicate(10,sample(0:1,1000,rep=TRUE)))
)
})
observeEvent(input$df_rows_selected, {
output$second_sub_item <- renderMenu({
menuSubItem("Second sub item", tabName = "second_sub_item")
})
updateTabItems(session, "tabs", "second_sub_item")
output$row_selected = renderPrint({
input$df_rows_selected
})
})
}
shinyApp(ui, server)
After clicking on a row of the df localised in the "first_sub_item", the ShinyApp should switch to the "second_sub_item", but it's doesn't work directly.
I have to click once by myself on the "second_sub_item" tab for the updateTabItems() function to work.
When "second_sub_item" is created in the UI, everything works, so the problem seems to come from renderMenu() but I can't solve it...
Thank you in advance for your help!
https://youtu.be/ZZmtN31chiA
I changed menuItemOutput to menuSubItem in your UI. Since it now already exists you don't need to render it again. When you now click on a row it will jump straight to your second menu item. Does this solve your problem?
library(shiny)
library(DT)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("First item", "first_item",
actionButton("action_button", "Action"),
menuSubItem("First sub item", "first_sub_item")
),
menuItem("Second item", "second_item",
menuSubItem("Second sub item", "second_sub_item") #change to menuSubItem
)
)
),
dashboardBody(
tabItems(
tabItem("first_sub_item",
DT::dataTableOutput("df")
),
tabItem("second_sub_item",
verbatimTextOutput('row_selected')
)
)
)
)
server <- function(input, output, session){
observeEvent(input$action_button, {
output$df <- DT::renderDataTable(
as.data.frame(replicate(10,sample(0:1,1000,rep=TRUE)))
)
})
observeEvent(input$df_rows_selected, {
#Remove rendering of menuSubItem
updateTabItems(session, "tabs", "second_sub_item")
})
output$row_selected = renderPrint({
input$df_rows_selected
})
}
shinyApp(ui, server)
library(shiny)
library(tidyverse)
library(leaflet)
library(shinydashboard)
library(RColorBrewer)
library(viridis)
library(shinyWidgets)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")
),
menuItem("Widgets", tabName = "widgets", icon = icon("th"))
)
),
dashboardBody(
# Boxes need to be put in a row (or column)
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
box(plotOutput("plot1", height = 250)),
box(
title = "Controls",
sliderInput("slider", "Number of observations:", 1, 100, 50)
)
)
),
# Second tab content
tabItem(tabName = "widgets",
h2("Widgets tab content")
)
)
)
)
server <- function(input, output) {
set.seed(122)
histdata <- rnorm(500)
output$plot1 <- renderPlot({
data <- histdata[seq_len(input$slider)]
hist(data)
})
}
shinyApp(ui, server)
The above example, the output renders when the tabs dashboard and widgets are clicked seperately. In the dashboard tab, i have my slider input in the body.
Now when I change my slider to have it at the sidebar:
library(shiny)
library(tidyverse)
library(leaflet)
library(shinydashboard)
library(RColorBrewer)
library(viridis)
library(shinyWidgets)
ui = dashboardPage(
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
sidebarMenu(
id = "sidebarmenu",
menuItem("menuItem1",
tabName = "tab1",
sliderInput("slider", "Number of observations:", 1, 100, 50)
)
,
menuItem("menuItem2", tabName = "tab2")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "tab1",
tableOutput("myTable"),
),
tabItem(tabName = "tab2",
h2("Placeholder Cloud"),
plotOutput("myPlot"))
)
)
)
server <- function(input, output, session) {
tableData = reactiveVal(data.frame(x = 1:10, y = LETTERS[1:10]))
plotData = reactiveVal()
observeEvent(input$sidebarmenu, {
if(input$sidebarmenu == "tab2"){
#Code for tab 2
req(is.null(plotData()))
print("Tab 2 code is run")
plotData(runif(100))
}
})
output$myTable = renderTable({
tableData()
})
set.seed(122)
histdata <- rnorm(500)
output$myPlot = renderPlot({
data <- histdata[seq_len(input$slider)]
hist(data)
})
}
shinyApp(ui, server)
Problem here:
1) The text placeholder cloud, initially only rendered when the tab menuItem2 is clicked, now gets rendered together with the histogram which was supposed to render only when i clicked menuItem1
2) clicking on menuItem2 does not do anything. I would like to have tab2 when clicked, show a scatterplot as seen in this below block of code.
i.e., i would like to "integrate the below 3rd block of code" into the 2nd, the above so when i run the second block of code, when i click tab1, the input for the slider appears and renders the histogram. when i click tab2, the scatterplot will be rendered
library(shiny)
library(tidyverse)
library(leaflet)
library(shinydashboard)
library(RColorBrewer)
library(viridis)
library(shinyWidgets)
ui = dashboardPage(
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
sidebarMenu(
id = "sidebarmenu",
menuItem("menuItem1",
tabName = "tab1")
,
menuItem("menuItem2", tabName = "tab2")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "tab1",
tableOutput("myTable")),
tabItem(tabName = "tab2",
h2("Placeholder Cloud"),
plotOutput("myPlot"))
)
)
)
server <- function(input, output, session) {
tableData = reactiveVal(data.frame(x = 1:10, y = LETTERS[1:10]))
plotData = reactiveVal()
observeEvent(input$sidebarmenu, {
if(input$sidebarmenu == "tab2"){
#Code for tab 2
req(is.null(plotData()))
print("Tab 2 code is run")
plotData(runif(100))
}
})
output$myTable = renderTable({
tableData()
})
output$myPlot = renderPlot({
plot(plotData())
})
}
shinyApp(ui, server)
Any help is appreciated.I am new to Shiny.
for your 2nd part you said "clicking on menuItem2 does not do anything."... but you don't have any action for menuItem2 see
menuItem("menuItem2", tabName = "tab2")
I'm trying to dynamically generate a menuItem upon the creation of an object or click of a button (Ideally object). I have tried multiple methods and cannot seem to figure out a clean, working solution.
I have a lot of code so below shall include example code:
ui <- fluidPage(
dashboardPage(
dashboardHeader(title = "text"),
dashboardSidebar(
sidebarMenu(id = 'MenuTabs',
menuItem("Tab1", tabName = "tab1", selected = TRUE)
# menuItem("Tab1", tabName = "tab2")
)
),
dashboardBody(
tabItems(
tabItem("tab1",
actionButton("newplot", "New plot")),
tabItem("tab2",
plotOutput('Plot'))
)
)
)
)
server <- function(input, output, session){
output$Plot <- renderPlot({
input$newplot
cars2 <- cars + rnorm(nrow(cars))
plot(cars2)
})
}
shinyApp(ui, server)
Above I have 2 tabs, 1 with a button (shown), and another with a plot (hidden).
How can I get the hidden tab with the plot to appear upon clicking the button?
For bonus points, assuming the button instead created an object, how could I show the hidden menuItem given the creating of said object
Thanks
I've managed to solve it. Below is the code that will create a menuItem by pressing a button show.
ui <- fluidPage(
dashboardPage(
dashboardHeader(title = "text"),
dashboardSidebar(
sidebarMenu(id = 'MenuTabs',
menuItem("Tab1", tabName = "tab1", selected = TRUE),
# menuItem("Tab1", tabName = "tab2")
uiOutput('ui')
)
),
dashboardBody(
tabItems(
tabItem("tab1",
actionButton("newplot", "New plot"),
actionButton("show", "Show")),
tabItem("tab2",
plotOutput('Plot'))
)
)
)
)
server <- function(input, output, session){
output$Plot <- renderPlot({
input$newplot
# Add a little noise to the cars data
cars2 <- cars + rnorm(nrow(cars))
plot(cars2)
})
output$ui <- renderUI({
if(input$show == 0) return()
print(input$show)
sidebarMenu(id = 'MenuTabs',
menuItem("Tab1", tabName = "tab2")
)
})
}
shinyApp(ui, server)
I am using shinydashboard to create the interface of my shiny App. However I want one input which appear in the two tabMenu. In the example below, I want to textInput i_test appears in menu menu1 and menu2.
How should I implement it? Thanks for any suggestions.
library(shiny)
library(shinydashboard)
# Side bar boardy
sidebar <- dashboardSidebar(
sidebarMenu(
id = 'menu_tabs'
, menuItem('menu1', tabName = 'menu1')
, menuItem('menu2', tabName = 'menu2')
, menuItem('menu3', tabName = 'menu3')
)
)
# Body board
body <- dashboardBody(
tabItems(
tabItem(
tabName = 'menu1',
textInput('i_test', 'Test')
),
tabItem(
tabName = 'menu2'
)
)
)
# Shiny UI
ui <- dashboardPage(
title = 'test',
dashboardHeader(),
sidebar,
body
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
It seems that shiny always renders two distinct elements, even if you try to build the same element a second time.
Thats why i could only come up with a solution that only makes it look like the two text iputs are the same.
Check the Code:
library(shiny)
library(shinydashboard)
# Side bar boardy
sidebar <- dashboardSidebar(
sidebarMenu(
id = 'menu_tabs'
, menuItem('menu1', tabName = 'menu1')
, menuItem('menu2', tabName = 'menu2')
, menuItem('menu3', tabName = 'menu3')
)
)
# Body board
body <- dashboardBody(
tabItems(
tabItem(
tabName = 'menu1',
textInput('i_test_1', 'Test')
),
tabItem(
tabName = 'menu2',
textInput('i_test_2', 'Test')
),
tabItem(
tabName = 'menu3'
)
)
)
# Shiny UI
ui <- dashboardPage(
title = 'test',
dashboardHeader(),
sidebar,
body
)
server <- function(input, output, session) {
observe({
text1 <- input$i_test_1
updateTextInput(session, 'i_test_2', value = text1)
})
observe({
text2 <- input$i_test_2
updateTextInput(session, 'i_test_1', value = text2)
})
}
shinyApp(ui, server)
I have 3 selectInput boxes and a pool of 4 options which can be selected by these 3 boxes. I want the options displayed by the selectInputs to change dynamically as other selectInputs are selected. However I want the "NONE" option to be available at all points of time for all the three boxes. The code I am using is
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic selectInput"),
dashboardSidebar(
sidebarMenu(
menuItemOutput("menuitem")
)
),
dashboardBody(
uiOutput('heirarchy1'),
uiOutput('heirarchy2'),
uiOutput('heirarchy3')
)
)
server <- function(input, output) {
output$menuitem <- renderMenu({
menuItem("Menu item", icon = icon("calendar"))
})
heirarchy_vector<-c("NONE","A","B","C")
output$heirarchy1<-renderUI({
selectInput("heir1","Heirarchy1",c("NONE",setdiff(heirarchy_vector,c(input$heir2,input$heir3))),selected="NONE")
})
output$heirarchy2<-renderUI({
selectInput("heir2","Heirarchy2",c("NONE",setdiff(heirarchy_vector,c(input$heir1,input$heir3))),selected="NONE")
})
output$heirarchy3<-renderUI({
selectInput("heir3","Heirarchy3",c("NONE",setdiff(heirarchy_vector,c(input$heir1,input$heir2))),selected="NONE")
})
}
shinyApp(ui, server)
Any help on this will be greatly appreciated
EDIT
I tried using updateSelectInput for this purpose. However the code doesn't seem to run
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic selectInput"),
dashboardSidebar(
sidebarMenu(
menuItemOutput("menuitem")
)
),
dashboardBody(
selectInput("heir1","Heirarchy1",c("NONE","A","B","C"),selected="NONE"),
selectInput("heir2","Heirarchy2",c("NONE","A","B","C"),selected="NONE"),
selectInput("heir3","Heirarchy3",c("NONE","A","B","C"),selected="NONE")
)
)
server <- function(input, output) {
output$menuitem <- renderMenu({
menuItem("Menu item", icon = icon("calendar"))
})
heirarchy<-c("A","B","C")
observe({
hei1<-input$heir1
hei2<-input$heir2
hei3<-input$heir3
choice1<-c("NONE",setdiff(heirarchy,c(hei2,hei3)))
choice2<-c("NONE",setdiff(heirarchy,c(hei1,hei3)))
choice3<-c("NONE",setdiff(heirarchy,c(hei1,hei2)))
updateSelectInput(session,"heir1",choices=choice1)
updateSelectInput(session,"heir2",choices=choice2)
updateSelectInput(session,"heir3",choices=choice3)
})
}
shinyApp(ui, server)
You're close! Two things, you need to assign the session variable when you start your server instance, also when you update the select inputs you need to set which choice was selected, other than that everything looks OK. Try this:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic selectInput"),
dashboardSidebar(
sidebarMenu(
menuItemOutput("menuitem")
)
),
dashboardBody(
selectInput("heir1","Heirarchy1",c("NONE","A","B","C"),selected="NONE"),
selectInput("heir2","Heirarchy2",c("NONE","A","B","C"),selected="NONE"),
selectInput("heir3","Heirarchy3",c("NONE","A","B","C"),selected="NONE")
)
)
server <- function(input, output, session) {
output$menuitem <- renderMenu({
menuItem("Menu item", icon = icon("calendar"))
})
heirarchy<-c("A","B","C")
observe({
hei1<-input$heir1
hei2<-input$heir2
hei3<-input$heir3
choice1<-c("NONE",setdiff(heirarchy,c(hei2,hei3)))
choice2<-c("NONE",setdiff(heirarchy,c(hei1,hei3)))
choice3<-c("NONE",setdiff(heirarchy,c(hei1,hei2)))
updateSelectInput(session,"heir1",choices=choice1,selected=hei1)
updateSelectInput(session,"heir2",choices=choice2,selected=hei2)
updateSelectInput(session,"heir3",choices=choice3,selected=hei3)
})
}
shinyApp(ui, server)