First of all let me give you a bit of context related to my problem. I am using shiny, shinyjs and shinydashboard to create a dynamic Shiny App. ShinyDashboard being used for the pretty layout of sidebar & header, and shinyjs to dynamically hide/show specific elements of the app depending on the users actions.
Now, regarding what I aim to achieve, I would like to have a specific tab of my app to be hidden (non visible to user) at startup. I know that this has been covered multiple times already on SO, but couldn't find anything related directly to my problem. Indeed, while I have no issues using shinyjs on almost every element of the UI (ex: tabItem, fileInput, specific div) to hide elements using the shinyjs::hidden() function, it seems that it doesn't work for a tabPanel inside a tabBox (see example in MWE). In my example below, I would like to have the tab "Analysis Setup" hidden at the start and shown later again to user after some action (using shinyjs::show()).
Please note that I desire to use a tabBox and not a tabSetPanel for esthetic reasons, and that I suspect the issue to be linked to the naming / IDing which is a bit specific when using shinyjs in conjunction with shinyDashboard (I remember reading this somewhere on SO from a response by Dan Ataali). This also results from a test I have made where:
shinyjs::toggle(id = "analysis_setup_tab") and shinyjs::toggle(id = "shiny-tab-analysis_setup_tab")does not work.
But shinyjs::toggle(selector = "#generalData_tabBox li a[data-value=analysis_setup_tab]") works
So I expect that shinyjs:hidden() would also need some change to apply correctly on the tab. But I do not know what to change. Note that I am quite unfamiliar with the selctor / li type of accessing elements and I do not know javascript.
Please note that I have also tried the following without success:
extendShinyjs(text = jsCode, functions = c("init")), &
shinyjs.init = function(){ $('#generalData_tabBox li a[data-value=analysis_setup_tab]').hide();}"
Please find below a minimum working example (MWE) to illustrate the problem.
library(shiny)
library(shinyjs)
library(shinydashboard)
library(rlist)
library(DT)
# Global variables
use_userGuide <<- TRUE
counter <<- 0
counter_2 <<- 0
ui <- function(request) {
### Build global dashboard
dashboardPage(
dashboardHeader(title = div("Header")),
dashboardSidebar(sidebarMenuOutput(outputId = "sidebar_menu")),
dashboardBody(
useShinyjs(),
uiOutput("body"))
)
}
menuItem_cover <- tabItem(tabName = "cover_tab", class="active",
fluidPage(
mainPanel(width = 12,
div("This is the cover page")
)))
menuItem_userGuide <- tabItem(tabName = "user_guide_tab",
fluidPage(
mainPanel(width = 12,
div("Some user guide stuff")
)))
menuSubItem_generalData <-
tabItem(tabName = "generalData_tab",
fluidPage(mainPanel(width = 12,
tabBox(id="generalData_tabBox", width = 12,
tabPanel("Portfolio",
value = 'portfolio_tab',
fluidRow(
## Load file from local
column(width = 12,
shinyjs::hidden(fileInput(
"portfolio",
"Select CSV File with Portfolio data",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")))
)
)
), # end of tabPanel
shinyjs::hidden(
tabPanel("Analysis Setup",
value = 'analysis_setup_tab',
fluidRow(
column(width = 12,
div(id="analysis_div",
DT::dataTableOutput("analysis_setup_dt")
)
) # Column end
) # fluid row end
) # Tabpanel
) # end of hidden
))))
server <- function(input, output, session) {
## Initalisation of tabs in body
body_list <- list(menuItem_cover)
if(use_userGuide){body_list <- list.append(body_list,menuItem_userGuide)}
body_list <- list.append(body_list,menuSubItem_generalData)
## Include items generated into the main body ##
mainbody <<- do.call(tabItems, body_list)
## Render - Body ##
output$body <- renderUI({
div(mainbody)
})
# Setup sidebar content - serverside
{
# Initial empty list
menu_list <- list()
# Add user guide tab
if(use_userGuide){menu_list <- list.append(menu_list,menuItem("User Guide", tabName = "user_guide_tab"))}
# Other tabs of the sidebar
menu_list <- list.append(menu_list,
# Data Inputs
menuItem("Data",
tabName = "dataG_tab",
menuSubItem("General", tabName = "generalData_tab", selected = TRUE),
# Load - button
div(
align = "center",
actionButton("toggleAnalysis", "Toggle Analysis"),
style = 'border-left:#fff;'
),
# Load - button
div(
align = "center",
actionButton("togglePortfolio", "Toggle Portfolio"),
style = 'border-left:#fff;'
)
)
)
# Make it a reactive list
menu_vals = reactiveValues(menu_list = menu_list)
}
## Render - Sidebar ##
output$sidebar_menu <- renderMenu({
menu_list <- list(menu_vals$menu_list)
sidebarMenu(id="sidebar_menu",.list = menu_list)
})
output$analysis_setup_dt <- renderDataTable({mtcars})
# If clicked make tab visible
observeEvent(input$togglePortfolio, {
shinyjs::toggle(id="portfolio")
})
# If clicked make tab visible
observeEvent(input$toggleAnalysis, {
#toggle(id="analysis_setup_tab") # Doesn't work (need selector)
shinyjs::toggle(selector = "#generalData_tabBox li a[data-value=analysis_setup_tab]")
})
}
shinyApp(ui, server)
Thank you very much in advance for your help. It would be highly appreciated.