Creating ID for R Shiny Module UI Inputs

Good morning,

I am very new to shiny modules and finally have been able to pass module values between modules. However, I'd like to hide certain parts of the module UI based on what tab the user is on. I can do this when I don't use modules as shown below.

checkboxInput(inputId = "parGlobal_hideNarrative", label = "HIDE NARRATIVE"),
sidebarMenu(
id= "smID",
menuItem("Home", tabName = "tn_homePage")

observe({
if(input$smID == "tn_homePage") # it requires a sidebarMenu ID to reference it
{shinyjs::hide("parGlobal_hideNarrative")}
else {shinyjs::show("parGlobal_hideNarrative")}
})

However, I can't seem to reference the module components like the above solution.

#First successful module!
modUI_parGlobalSchsacRegionChbCounty(id = "parGlobal", df_mnRegionChbCounty),
shinydashboard::sidebarMenu(
id= "smID", #By having sidebarMenu id, I can reference it and hide other filters with shinyjs

module UI modUI_parGlobalSchsacRegionChbCounty <- function(id, df) {
ns <- NS(id)
tagList(
#Check box will be used on every tab to hide some sort of narrative
checkboxInput(ns("parGlobal_hideNarrative"), label = "HIDE NARRATIVE"),
selectInput(
ns("parGlobal_county"),
label= "Select County",
choices= sort(unique(df$county)),
selected= "Kittson",
multiple= FALSE,
width= 350
),
selectInput(
ns("parGlobal_schsacRegion"),
label= "Select SCHSAC Region",
choices= NULL,
selected= NULL,
multiple= FALSE,
width= 350
),
selectInput(
ns("parGlobal_chb"),
label= "Select Community Health Board",
choices= NULL,
selected= NULL,
multiple= FALSE,
width= 350
)
)
}

observe({
if (input$smID == "tn_home" )
{
shinyjs::hide("parGlobal-parGlobal_schsacRegion-selectized")
}
else
{
shinyjs::show("parGlobal-parGlobal_schsacRegion-selectized")
}
})

The reason I was hoping the above worked is this is the tabindex id as shown in the image.

image

Is there a way to easily hide and show module UI elements based on the user's selections? Like can I give the Module an ID and then reference each component? I was hoping for a syntax like parGlobal$parGlobal_shcsacRegion but this doesn't seem to work.

Thank you

Hi @polson01 ,

could you please come up with a more compact example.

In order to reproduce what you did i would need to come up with a df and the the application logic around the module you posted which will probably end up in something you don't want.

Use something like the iris dataset which is shipped in R . Then you will receive feedback on your problem since this is definitely solvable.

Here is an example.
the module is primitive showing always a div with id 'a' and content'a' and also a div id 'b' and content 'b'.
the module takes a reactive input (so it can react to) the tab selection in the wider app.
Its internals decide whether to show a or b based on the tab selection.

library(shiny)
library(shinydashboard)
library(shinyjs)


exampleModUI <- function(id) {
  ns <- NS(id)
  tagList(
    div(id=ns("a"),
        "a"),
    div(id=ns("b"),
        "b")
  )
}

exampleModServer <- function(id,tab_sel) {
  moduleServer(
    id,
    function(input, output, session) {
      stopifnot(is.reactive(tab_sel))
      observeEvent(tab_sel(),{
        if(tab_sel()=='dashboard'){
          shinyjs::hide(id = "b")
          shinyjs::show(id = "a")
        } else {
            shinyjs::hide(id = "a")
            shinyjs::show(id = "b")
          
        }
      })
    }
  )
}



header <- dashboardHeader()

sidebar <- dashboardSidebar(
  sidebarMenu(
    # Setting id makes input$tabs give the tabName of currently-selected tab
    id = "mynavtabs",
    menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
    menuItem("Widgets", icon = icon("th"), tabName = "widgets", badgeLabel = "new",
             badgeColor = "green"),
  p("Showing what tab is selected:"),
  verbatimTextOutput("show_selected_tab")
  
))

body <- dashboardBody(
  tabItems(
    tabItem("dashboard",
            div(p("Dashboard tab content"),
                exampleModUI("md"))
    ),
    tabItem("widgets",
            div("Widgets tab content",
                exampleModUI("mw"))
    )
  )
)

shinyApp(
  ui = tagList(useShinyjs(),dashboardPage(header, sidebar, body)),
  server = function(input, output) { 
    
    output$show_selected_tab <- renderText({
      req(input$mynavtabs)
    })
    
    exampleModServer(id = "md",reactive(input$mynavtabs))
    exampleModServer(id = "mw",reactive(input$mynavtabs))
    
  }
)

Thank you both for the replies.

I decided to move my global inputs to the main application, so I don't have to pass my main data frame into the main app and then to the module to then pass it back to the main module based on the user selection. Based on Nirgrahamuk's solution, it appears we would apply the js hide show logic in the module rather than in the main application, so this would require more passing from the main app to the module where if the inputs are in the main app we don't have to pass the tab as an argument. Thank you Nirgrahamuk for sharing a solution, but what I was looking for is how to apply the shinyjs logic in the shinyApp, not the module.

Im sorry, I dont know what you are trying to do.
Maybe you can make an example, similar to how i gave you an example and that could be a basis to make changes to