Add dynamic tabs in shiny dashboard using conditional panel
You can dynamically create the ui
as per example below.
Example 1: Using RenderUI
rm(list = ls())
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
checkboxGroupInput("Tabs", label = h4("tabpanel"), choices = list("tabs" = "tabs"),selected = NULL),
checkboxGroupInput("MoreTabs", label = h4("moretabpanel"), choices = list("moretabs" = "moretabs"),selected = NULL)
),
dashboardBody(
uiOutput("ui")
)
)
server <- function(input, output) {
output$ui <- renderUI({
check1 <- input$Tabs == "tabs"
check2 <- input$MoreTabs == "moretabs"
if(length(check1)==0){check1 <- F}
if(length(check2)==0){check2 <- F}
if(check1 && check2){
tabBox(title = "intro",id= "ttabs", width = 8, height = "420px",
tabPanel("Files", dataTableOutput("Files")),
tabPanel("Files1", dataTableOutput("Files1"))
)
}
else if(check1){
tabBox(title = "intro",id= "ttabs", width = 8, height = "420px",tabPanel("Files", dataTableOutput("Files")))
}
else{return(NULL)}
})
}
shinyApp(ui, server)
Example 2: Using conditionalPanel
rm(list = ls())
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
checkboxGroupInput("Tabs", label = h4("tabpanel"), choices = list("tabs" = "tabs"),selected = NULL),
checkboxGroupInput("MoreTabs", label = h4("moretabpanel"), choices = list("moretabs" = "moretabs"),selected = NULL)
),
dashboardBody(
conditionalPanel(
condition = "input.MoreTabs == 'moretabs' && input.Tabs == 'tabs'",
tabBox(
title = "intro",
id= "ttabs", width = 8, height = "420px",
tabPanel("Files",value=1, dataTableOutput("Filesa")),
tabPanel("Files1",value=2, dataTableOutput("Files1a"))
)
),
conditionalPanel(
condition = "input.Tabs == 'tabs' && input.MoreTabs != 'moretabs'",
tabBox(
title = "intro",
id= "ttabs", width = 8, height = "420px",
tabPanel("Files",value=3, dataTableOutput("Files"))
))
))
server <- function(input, output) { }
shinyApp(ui, server)
How to create a shiny App where tabs are only become visible if a condition is met
you can find a solution to conditional tabsets in the link below, this is done on the server side with renderUI()
and shown achieved with conditional panels
Add dynamic tabs in shiny dashboard using conditional panel
A closer example of adding tabs to an existing tab set can be achieved with the code below (derived from examples in the original link):
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
checkboxGroupInput("Tabs", label = h4("tabpanel"), choices = list("tabs" = "tabs"),selected = NULL),
checkboxGroupInput("MoreTabs", label = h4("moretabpanel"), choices = list("moretabs" = "moretabs"),selected = NULL)
),
dashboardBody(
tabBox(id="x",tabPanel("panel","panel"))
)
)
server <- function(input, output) {
observeEvent(input$Tabs,{
check1 <- input$Tabs == "tabs"
if(check1&!is.na(check1)){
insertTab(inputId = "x",
tabPanel("Dynamic", "This a dynamically-added tab"),target="panel",position ="after")
}
})
}
shinyApp(ui, server)
We use the function insertTab
to append a tab to an existing tabset based on an event. (checking a box) if you want to subsequently remove this tab if the condition becomes unsatisfied again you can use removeTab
more information on these functions can be found here:
Shiny Insert Tab
Dynamic menu in shinydashboard with conditionalPanel
You can render your menu in the server based on user input or other conditions, and output that to the UI. Working example below:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
selectInput("userrights", label = "User Rights:",
choices = c("Read + Write", "Read")),
sidebarMenuOutput("menu")
),
dashboardBody(
tabItems(
tabItem("a", h1("A was done")),
tabItem("b", h1("B was done"))
)
)
)
server <- function(input, output) {
output$menu <- renderMenu({
my_list = list(menuItem("a", tabName="a"))
if(input$userrights=="Read + Write")
my_list[[2]] = menuItem("b", tabName="b")
sidebarMenu(my_list)
})
}
runApp(shinyApp(ui, server))
Hope this helps!
Shinydashboard multiple conditions in conditionalPanel with same inputs
The condition in conditionalPanel
is a JavaScript expression, not a R expression.
So you have to replace
input.menu1 == 'dashboard' && input.tabselected %in% c('1','2')
with
input.menu1 == 'dashboard' && (input.tabselected == '1' || input.tabselected == '2')
or
input.menu1 == 'dashboard' && ['1','2'].indexOf(input.tabselected) > -1
Navigate in the same dynamic tabPanel based on if condition in shiny app
- You had a few things going on, one is that the creation of
dyntab
was happening every time you change a tab, which is now been fixed to render only once on start - We shall take advantage of the
shinyjs
with itsshow
andhide
functions to show theradioButtons
instead of creating it all the time withrenderUI
- Im still not 100% on the using the above approach in the
dyntab
as you can see I had to create theid
for thediv
in order toshow
andhide
it, this happens because it assigns randomid
to the tables and the charts you're rendering - I've also took advantage of
hidden
function to hide the div upon start
Uni <- data.frame(NAME=c("Iris","Mtcars"))
options(stringsAsFactors = F)
# app.R ##
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyjs)
library(DT)
dbHeader <- dashboardHeaderPlus(
title = "Tabs"
)
ui <- dashboardPagePlus(
dbHeader,
dashboardSidebar(
hidden(
radioButtons("radioV2", label = "Choose Mode",choices = c("Table","Plot"), selected = "Table")
)
),
dashboardBody(
useShinyjs(),
tags$hr(),
tabsetPanel(
id ="tabA",
type = "tabs",
tabPanel("Front",icon = icon("accusoft")),
tabPanel("Data", icon = icon("table"), uiOutput("dyntab")
)
)
)
)
server <- function(input, output, session) {
observeEvent(input$tabA,{
if(input$tabA == "Front"){
hide("radioV2")
}
else{
show("radioV2")
}
})
output$dyntab <- renderUI({
do.call(tabsetPanel,
c(id='tabB',
type="tabs",
lapply(1:nrow(Uni), function(i) {
tabPanel(Uni[i,],icon = icon("table"),
div(id = paste0("Table",Uni$NAME[i]),DT::renderDataTable({
if(Uni$NAME[i] == "Iris"){
datatable(iris)
}else{
datatable(mtcars)
}
})),
hidden(div(id = paste0("Plot",Uni$NAME[i]),renderPlot({
if(Uni$NAME[i] == "Iris"){
plot(iris)
}else{
plot(mtcars)
}
})
))
)
})
)
)
})
observeEvent(input$radioV2,{
print(paste0(input$radioV2,input$tabB))
if(input$radioV2 == 'Table'){
show(paste0("Table",input$tabB))
hide(paste0("Plot",input$tabB))
}else{
hide(paste0("Table",input$tabB))
show(paste0("Plot",input$tabB))
}
})
}
shinyApp(ui = ui, server = server)
Adding different kinds of tabs in Shiny Dashboard (after do.call)
If I correctly understand, you want:
Some_List <- c("IR", "FX", "EQ")
Some_Long_List <- c("Aggregated Things", "Component 1", "Component 2")
do.call(
tabItems,
c(
lapply(
1:length(Some_List),
function(i) {
tabItem(
tabName = paste0(Some_List[i],"_tab"),
h2(Some_Long_List[i]),
fluidPage(
fluidRow(
column(
3,
dateInput(paste0("ME_DATE_output_",Some_List[i]),label=h2("Select a Date"), value="2020-05-29")
,hr()
,actionButton(paste0("calculate_",Some_List[i]), paste0("Calculate ",Some_List[i]),class = "btn-md btn-primary" )
)
,column(
9,
column(verbatimTextOutput(paste0("file_path_",Some_List[i])),width=12),
hr(),
selectInput(paste0('select_file_',Some_List[i]),'Select a File to display', choices=NULL),
hr(),
column(dataTableOutput(paste0('selected_table_',Some_List[i])),width=12)
)
)
)
)
}
),
list(
tabItem(
tabName = "Comparison",
h2("Data Comparison"),
fluidPage(
fluidRow(
column(
3,
fileInput('Dat1', 'Choose First Data:', accept = c(".csv", ".txt")),
fileInput('Dat2', 'Choose Second Data:', accept = c(".csv", ".txt"))
),
column(
9,
tableOutput('Comparison_Results')
)
)
)
)
)
)
)
Dynamically Generate Plots in Conditional Tabs using renderUI in Shiny
Your example isn't exactly minimal so i did some stripping away. First the data and helper functions
library(shiny)
library(ggplot2)
channels = c("Affiliate","Email","Media","SEO")
nObs = c(round(runif(1,100,200)))
myData = data.frame(
Campaign = unlist(lapply(channels, FUN = function(x) paste(x,seq(from=1,to=nObs,by=1),sep=""))),
Channel = rep(channels,nObs),
Return = runif(nObs*length(channels),50,500),
Spend = runif(nObs*length(channels),10,100)
)
plotSingle = function(myData, channelName){
ggplot(myData[which(myData$Channel==channelName),], aes(x = Spend, y = Return)) +
geom_point(color="black") +
theme(panel.background = element_rect(fill = 'grey85'),
panel.grid.major = element_line(colour = "white"))
}
Now the UI
ui <- fluidPage(
headerPanel('Plot Testing'),
mainPanel(
uiOutput('mytabs'),
plotOutput('scatterPlot')
)
)
Note that we only use one plotOutput here. What we will do is just change the plot it's showing based on the currently selected tab. Here's the server code
server = function(input, output) {
rawData <- reactive({
myData
})
output$mytabs = renderUI({
if(is.null(rawData())){return ()}
channels = unique(rawData()$Channel)
myTabs = unname(Map(tabPanel, channels))
do.call(tabsetPanel, c(myTabs, id="channeltab"))
})
output$scatterPlot <- renderPlot({
if(is.null(rawData()) | is.null(input$channeltab)){return ()}
plotSingle(rawData(), input$channeltab)
})
}
You see we set an id
on the tabsetPanel
we create. We can then use that as input
to determine which panel is selected and show the correct plot. All run with
shinyApp(ui = ui, server = server)
Related Topics
How Calculate Growth Rate in Long Format Data Frame
R: Serialize Objects to Text File and Back Again
Warning When Defining Factor: Duplicated Levels in Factors Are Deprecated
Sum Multiple Columns by Group with Tapply
How to Change Color of Facet Borders When Using Facet_Grid
Shiny + Ggplot: How to Subset Reactive Data Object
How Does One Merge Dataframes by Row Name Without Adding a "Row.Names" Column
How to Apply a Hierarchical or K-Means Cluster Analysis Using R
Passing a 'Data.Table' to C++ Functions Using 'Rcpp' And/Or 'Rcpparmadillo'
Taking a Disproportionate Sample from a Dataset in R
Scoping and Functions in R 2.11.1:What's Going Wrong
Tm: Read in Data Frame, Keep Text Id'S, Construct Dtm and Join to Other Dataset
R: How to Make a Barplot with Labels Parallel (Horizontal) to Bars
Convert Begin and End Coordinates into Spatial Lines in R