Related
I'm working on a shiny app with dynamic rendering. When the user uncheck the box, he must have an output with 8 wellPanel and when the box is checked, he must have two wellPanel. I used the function renderUI to generate output but when the box is unchecked, I only have 4 wellPanel instead of 8. This is what I did :
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
body <- dashboardBody(
tabItems(
tabItem(tabName = "menutab1",
checkboxInput(inputId = "my_id", "check the box", value = TRUE),
####### renderUI #####
uiOutput("results")
)
)
)
ui <- dashboardPage(
title = "test",
options = list(sidebarExpandOnHover = TRUE),
header = dashboardHeader(disable = FALSE),
sidebar = dashboardSidebar(
minified = TRUE, collapsed = TRUE,
sidebarMenu(id="mymenu",
menuItem("first", tabName = "tab1", icon = icon("fas fa-acorn"),
menuSubItem('menu 1',
tabName = 'menutab1',
icon = icon('fas fa-hand-point-right'))
)
)
),
body
)
############# SERVER ############
server <- function(input, output) {
output$results <- renderUI({
if(input$my_id){
# object 1
fluidRow(
column(6,
wellPanel(
h1("A")
),
br(),
wellPanel(
h1("B")
)
)
)
} else {
# object 2 : doesnt show, why ?
fluidRow(
column(6,
wellPanel(
h1("C")
),
br(),
wellPanel(
h1("D")
)
),
column(6,
wellPanel(
h1("E")
),
br(),
wellPanel(
h1("F")
)
)
)
# object 3 : I only got this
fluidRow(
column(6,
wellPanel(
h1("H")
),
br(),
wellPanel(
h1("I")
)
),
column(6,
wellPanel(
h1("J")
),
br(),
wellPanel(
h1("K")
)
)
)
}
})
}
############# RUN #############
shinyApp(ui = ui, server = server)
How can we fix that ?
Some help would be appreciated
The problem with your above code is, that only the last object of the else statement is returned. You can wrap both fluidRows in a tagList to get the desired output.
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
body <- dashboardBody(tabItems(tabItem(
tabName = "menutab1",
checkboxInput(inputId = "my_id", "check the box", value = TRUE),
uiOutput("results")
)))
ui <- dashboardPage(
title = "test",
options = list(sidebarExpandOnHover = TRUE),
header = dashboardHeader(disable = FALSE),
sidebar = dashboardSidebar(
minified = TRUE,
collapsed = TRUE,
sidebarMenu(
id = "mymenu",
menuItem(
"first",
tabName = "tab1",
icon = icon("fas fa-acorn"),
menuSubItem(
'menu 1',
tabName = 'menutab1',
icon = icon('fas fa-hand-point-right')
)
)
)
),
body
)
server <- function(input, output) {
output$results <- renderUI({
if (input$my_id) {
fluidRow(column(6,
wellPanel(h1("A")),
br(),
wellPanel(h1("B"))
)
)
} else {
tagList(
fluidRow(
column(6,
wellPanel(h1("C")),
br(),
wellPanel(h1("D"))),
column(6,
wellPanel(h1("E")),
br(),
wellPanel(h1("F")))
),
fluidRow(
column(6,
wellPanel(h1("H")),
br(),
wellPanel(h1("I"))),
column(6,
wellPanel(h1("J")),
br(),
wellPanel(h1("K")))
)
)
}
})
}
shinyApp(ui = ui, server = server)
I have at least 2 individual apps that I want to join in one single app. Although I was using shinyDashboard, I think that it could be a good idea to try with navbarPage.
However, I don't know if it is possible to do what I want with this new approach.
To put you in a context, this is an example of my shinyDashboard. Each tab has a sidebarPanel and mainPanel. I replicated the info in all the tabs, but the idea is that each tab has different things.
However, I was thinking to have this using navbarPage. Do you know if it is possible?
Here I attach you the code that I used for the shinyDashboard:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
## Sidebar content
dashboardSidebar(
sidebarMenu(
menuItem("Tab1", tabName = "Tab1", icon = icon("th")),
menuItem("Tab2", tabName = "Tab2", icon = icon("th")),
menuItem("Tab3", tabName = "Tab3", icon = icon("th"))
)
),
dashboardBody(
fluidRow(
tabItems(
tabItem(tabName = "Tab1",
sidebarPanel(
numericInput("num",
"Select a number",
min = 1,
value = 10),
checkboxInput("remove", "Remove...", value = FALSE),
sliderInput("slider", "slider", min = 1, max = 30, value=22)
),
mainPanel(
plotOutput("plot1")
)
),
tabItem(tabName = "Tab2",
sidebarPanel(
numericInput("num2",
"Select a number",
min = 1,
value = 10),
checkboxInput("remove2", "Remove...", value = FALSE),
sliderInput("slider2", "slider", min = 1, max = 30, value=22)
),
mainPanel(
plotOutput("plot2")
)
),
tabItem(tabName = "Tab3",
sidebarPanel(
numericInput("num3",
"Select a number",
min = 1,
value = 10),
checkboxInput("remove3", "Remove...", value = FALSE),
sliderInput("slider3", "slider", min = 1, max = 30, value=22)
),
mainPanel(
plotOutput("plot3")
)
)
)
)
)
)
server <- function(input, output, session) {
output$plot1 <- renderPlot({
plot(x=c(1,2,3,4,5,6), y=c(14,3,6,4,56,2))
})
output$plot2 <- renderPlot({
plot(x=c(1,2,3,4,5,6), y=c(14,3,6,4,56,2))
})
output$plot3 <- renderPlot({
plot(x=c(1,2,3,4,5,6), y=c(14,3,6,4,56,2))
})
}
shinyApp(ui, server)
And the code for the navbarPage approach:
library(shinythemes)
library(shiny)
ui <- fluidPage(theme = shinytheme("flatly"),
navbarPage(
collapsible = T,
fluid = T,
"",
tabPanel("Tab 1", "one"),
tabPanel("Tab 2", "two"),
tabPanel("Tab 3", "three"),
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
Thanks very much in advance
You can do that with sidebarLayout. Here I've done it for the first tabPanel:
library(shinythemes)
library(shiny)
ui <- fluidPage(
theme = shinytheme("flatly"),
navbarPage(
title = "Your App Title",
collapsible = TRUE,
fluid = TRUE,
tabPanel(
title = "Tab 1",
sidebarLayout(
sidebarPanel = sidebarPanel(
tags$h3(
"Sidebar Content Here!"
)
),
mainPanel = mainPanel(
tags$h3(
"Main Panel Content Here!"
)
)
)
),
tabPanel(
title = "Tab 2",
"three"
),
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
I would like to align the three boxes below from the UI part of an R shiny to the same horizontal level. They originally were on the same level, However, after I added the helper text ("Label:"), they are no longer on the same level. Any suggestion? Thank you. Below is a reproducible code.
library(shiny)
library(miniUI)
ui <- miniPage(
gadgetTitleBar(h3(strong("UI"), align="center"), left=NULL, right=NULL),
miniTabstripPanel(
miniTabPanel(strong("temp"),
miniContentPanel(
fluidRow(
column(4, radioButtons(inputId="subt", label="Step1:",
inline=TRUE, choices=c("YES", "NO"), selected="YES"),
conditionalPanel(
condition = "input.subt == 'YES'",
fluidRow(
column(4, textInput(inputId="subt.id", label="The step 1 is ...:", ""))
)
)
),
###
### Normalize the response
column(6, radioButtons(inputId="norm", label="Step2:",
inline=TRUE, choices=c("YES", "NO"), selected="YES"),
conditionalPanel(
condition = "input.norm == 'YES'",
fluidRow(align="center",
column(4, textInput(inputId="norm.start", label="step 2.1:", "")),
helpText("Label:"),
column(4, textInput(inputId="norm.from", label="step 2.2:", "")),
column(4, textInput(inputId="norm.to", label="step 2.3:", ""))
)
)
)
)
)
)
))
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
You can apply some css to align the label text.
div(helpText("Label:"),style = "margin-top: -35px"),
Complete code :
library(shiny)
library(miniUI)
ui <- miniPage(
gadgetTitleBar(h3(strong("UI"), align="center"), left=NULL, right=NULL),
miniTabstripPanel(
miniTabPanel(strong("temp"),
miniContentPanel(
fluidRow(
column(4, radioButtons(inputId="subt", label="Step1:",
inline=TRUE, choices=c("YES", "NO"), selected="YES"),
conditionalPanel(
condition = "input.subt == 'YES'",
fluidRow(
column(4, textInput(inputId="subt.id", label="The step 1 is ...:", ""))
)
)
),
###
### Normalize the response
column(6, radioButtons(inputId="norm", label="Step2:",
inline=TRUE, choices=c("YES", "NO"), selected="YES"),
conditionalPanel(
condition = "input.norm == 'YES'",
fluidRow(align="center",
column(4, textInput(inputId="norm.start", label="step 2.1:", "")),
div(helpText("Label:"),style = "margin-top: -35px"),
column(4, textInput(inputId="norm.from", label="step 2.2:", "")),
column(4, textInput(inputId="norm.to", label="step 2.3:", ""))
)
)
)
)
)
)
))
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
My Shiny app has a universal sidebarPanel. I want to hide it for one particular tab, i.e. whenever the used would navigate to that tab the sidebarPanel would collapse. The code I am trying is as follows-
The UI-
library(shiny)
shinyUI(fluidPage (
theme = shinytheme("superhero"),
headerPanel("COVID-19 Data Visualizer"),
sidebarPanel(
width = 2,
selectInput(
"countries",
label = "Select Countries",
choices =
c("B", "C", "A"),
selected = c("A"),
multiple = T
),
submitButton(text = "View")
),
mainPanel (h1(""),
tabsetPanel(
tabPanel(
"Global Status",
div(id="Main"),
plotlyOutput("figG"),
br(),
plotlyOutput("global_time"),
br(),
plotlyOutput("global_cfr"),
br(),
plotlyOutput("global_p"),
br(),
plotlyOutput("global_recov_dead")
),
tabPanel(
"Comparative Charts",
plotlyOutput("fig_confirm"),
br(),
plotlyOutput("fig_dead"),
br(),
plotlyOutput("fig_recov")
),
tabPanel(
"Ratio Analysis",
plotlyOutput("fig_confirm_S"),
br(),
plotlyOutput("fig_confirm_D"),
br(),
plotlyOutput("fig_Ratio"),
br(),
plotlyOutput("fig_cfr_print")
)
))
))
The server part-
server <- function(input, output) {
observeEvent(input$tabs == "Global Status", {
shinyjs::hide(id = "Main")
})
}
I don't really want to use the navbarPage and want single sidebarPanel for all the inputs.
A screenshot of the output I am getting-
Thanks in advance.
Here is an example:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
sidebarLayout(
sidebarPanel(
id="sidebar",
selectInput(
"countries", label = "Select Countries",
choices = c("B", "C", "A"), selected = "A",
multiple = TRUE
)
),
mainPanel(
tabsetPanel(
tabPanel(
"Global status",
sliderInput("s1", "slider 1", 0, 100, 20)
),
tabPanel(
"Comparative charts",
sliderInput("s2", "slider 2", 0, 100, 50)
),
tabPanel(
"Ratio analysis",
sliderInput("s3", "slider 3", 0, 100, 80)
),
id = "tabset"
),
id="main"
)
)
)
server <- function(input, output){
observeEvent(input[["tabset"]], {
if(input[["tabset"]] == "Comparative charts"){
hideElement(selector = "#sidebar")
removeCssClass("main", "col-sm-8")
addCssClass("main", "col-sm-12")
}else{
showElement(selector = "#sidebar")
removeCssClass("main", "col-sm-12")
addCssClass("main", "col-sm-8")
}
})
}
shinyApp(ui = ui, server = server)
I have a shiny app in which I have a radioButtons widget with four buttons. When none of them is clicked I want the tabsetPanel "tabC" to be displayed. If "About" is selected I do not want tabsetPanel at all and if "Section A,B or C" is selected I want the tabsetPanel "tabA" to be displayed.
#ui.r
ui <- fluidPage(
theme=shinytheme("slate") ,
# App title ----
titlePanel("Tabsets"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
uiOutput("rad")
),
# Main panel for displaying outputs ----
mainPanel(
uiOutput("tabers")
)
)
)
#server.r
library(shiny)
server = function(input, output) {
output$rad<-renderUI({
radioButtons("radio", label = "",
choices = list("About" = 1, "Sector A" = 2, "Sector B" = 3,"Sector C" = 4),
selected = character(0))
})
output$tabers<-renderUI({
if(input$radio=="Sector A"){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio=="Sector B"){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio=="Sector C"){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio=="About"){
}
else{
tabsetPanel(
id="tabC",
type = "tabs",
tabPanel("Global"),
tabPanel("Performance" )
)
}
})
}
I believe since your choices have numeric values, you need to compare input$radio with a numeric value, for example: if (input$radio == 2) for Sector A.
In addition, when no radio buttons are selected, input$radio should be NULL. You could check for that at the beginning, and if NULL, show your tabC.
Please let me know if this has the desired behavior.
library(shiny)
library(shinythemes)
#ui.r
ui <- fluidPage(
theme=shinytheme("slate") ,
# App title ----
titlePanel("Tabsets"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
uiOutput("rad")
),
# Main panel for displaying outputs ----
mainPanel(
uiOutput("tabers")
)
)
)
#server.r
server = function(input, output) {
output$rad<-renderUI({
radioButtons("radio", label = "",
choices = list("About" = 1, "Sector A" = 2, "Sector B" = 3,"Sector C" = 4),
selected = character(0))
})
output$tabers<-renderUI({
if(is.null(input$radio)) {
tabsetPanel(
id="tabC",
type = "tabs",
tabPanel("Global"),
tabPanel("Performance")
)
}
else if(input$radio==2){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio==3){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio==4){
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index")
)
}
else if(input$radio==1){
}
# Left last else in here but should not get called as is
else{
tabsetPanel(
id="tabC",
type = "tabs",
tabPanel("Global"),
tabPanel("Performance" )
)
}
})
}
shinyApp(ui, server)
Thinking a little about your app, look at this option using some fuctions from shinydashboar package.
library(shiny)
library(shinydashboard)
library(shinythemes)
#ui.r
ui <- fluidPage(
theme=shinytheme("slate") ,
# App title ----
titlePanel("Tabsets"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
sidebarMenu( id = "tab",
menuItem("Home", tabName = "home"),
menuItem("Sector A", tabName = "sect_a"),
menuItem("Sector b", tabName = "sect_b"),
menuItem("Sector c", tabName = "sect_c"),
menuItem("About", tabName = "about")
)
),
# Main panel for displaying outputs ----
mainPanel(
tabItems(
# Home tab
tabItem(
tabName = "home",
tabsetPanel(
id="tabC",
type = "tabs",
tabPanel("Global"),
tabPanel("Performance" ))
),
tabItem(
tabName = "sect_a",
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index"))
),
tabItem(
tabName = "sect_b",
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index"))
),
tabItem(
tabName = "sect_c",
tabsetPanel(
id="tabA",
type = "tabs",
tabPanel("Constituents"),
tabPanel("Clusters" ),
tabPanel("Index"))),
tabItem(tabName = "about")
)
)
)
)
#server.r
server = function(input, output) {
}
shinyApp(ui, server)