Add Dynamic Tabs in Shiny Dashboard Using Conditional Panel

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)

Sample Image

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

  1. 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
  2. We shall take advantage of the shinyjs with its show and hide functions to show the radioButtons instead of creating it all the time with renderUI
  3. Im still not 100% on the using the above approach in the dyntab as you can see I had to create the id for the div in order to show and hide it, this happens because it assigns random idto the tables and the charts you're rendering
  4. 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



Leave a reply



Submit