Shiny module with conditional panel htmlOuptut

Hello, I'm hoping this is a simple question. I'm trying to using conditionalPanel in a module to add htmlOutput. There have been quite a few posts about modules and conditionalPanels, and the addition of the ns parameter which I thought should resolve this. Here is the merge request for the fix that was implemented. Using the same example, I'm wondering what I'm doing wrong when trying to conditionally show htmlOutput. I've tried the old way of handling namespace and the new way with ns = ns.

I hope there's something obvious I'm doing wrong or a work around so that this is possible. I've also tried many combinations of using the ns with the id and not, etc. I still cannot get the htmlOutput selectInput to show on the module side click. Thoughts?

Thanks in advance!

library(shiny)

condpanelUI <- function(id) {
  ns <- NS(id)

  tagList(
    checkboxInput(ns("checkbox"), "Make module panel visible"),
    conditionalPanel(condition = "input.checkbox",
                     ns = ns,
                     "This is the module conditional panel"),
    #conditionalPanel(condition = paste0("input['",ns("checkbox"),"']"), #also tried this
    conditionalPanel(condition = "input.checkbox",
                     ns = ns,
                     htmlOutput(ns("selectInput")))
  )
}

condpanel <- function(input, output, session) {

  output$selectInput <- renderUI({

    ns <- session$ns

    selectInput(
      inputId = ns("selectInput"),
      label = "Conditional Input :",
      choices = c("A","B","C")
    )

  })

}

ui <- fluidPage(
  condpanelUI("foo"),
  checkboxInput("checkbox", "Make top-level panel visible"),
  conditionalPanel(condition = "input.checkbox", "This is the top-level conditional panel"),
  conditionalPanel(condition = "input.checkbox", htmlOutput("selectInput"))
)

server <- function(input, output, session) {

  output$selectInput <- renderUI({

    selectInput(
      inputId = "selectInput",
      label = "Conditional Input :",
      choices = c("A","B","C")
    )

  })

}

shinyApp(ui, server)

Hi @hlendway. You miss the callModule function in server function.

library(shiny)

condpanelUI <- function(id) {
  ns <- NS(id)
  
  tagList(
    checkboxInput(ns("checkbox"), "Make module panel visible"),
    conditionalPanel(condition = "input.checkbox",
                     ns = ns,
                     "This is the module conditional panel"),
    #conditionalPanel(condition = paste0("input['",ns("checkbox"),"']"), #also tried this
    conditionalPanel(condition = "input.checkbox",
                     ns = ns,
                     htmlOutput(ns("selectInput")))
  )
}

condpanel <- function(input, output, session) {
  
  output$selectInput <- renderUI({
    
    ns <- session$ns
    
    selectInput(
      inputId = ns("selectInput"),
      label = "Conditional Input A:",
      choices = c("A","B","C")
    )
    
  })
  
}

ui <- fluidPage(
  condpanelUI("foo"),
  checkboxInput("checkbox", "Make top-level panel visible"),
  conditionalPanel(condition = "input.checkbox", "This is the top-level conditional panel"),
  conditionalPanel(condition = "input.checkbox", htmlOutput("selectInput"))
)

server <- function(input, output, session) {
  
  callModule(condpanel, "foo")
  
  output$selectInput <- renderUI({
    
    selectInput(
      inputId = "selectInput",
      label = "Conditional Input B :",
      choices = c("A","B","C")
    )
    
  })
  
}

shinyApp(ui, server)
2 Likes

@raytong, thanks for pointing that out and thanks for the quick response! That was a mistake when oversimplifying my example. Adding the addModule does make that work. My example is actually slightly more complex, I'm trying to render inputs based on the input tab, which works just fine in the main UI but not in the module. Again I hope it's something simple I'm overlooking. I created a slightly more complicated example to show my exact issue.

The filters should pop up when you go to the detail tab, you will see only the filters from the main UI appear and not the module. Hopefully just something I'm overlooking. Thanks again in advance for any thoughts and help.

library(shiny)
library(shinydashboard)

condpanelUI <- function(id) {
  ns <- NS(id)

  tagList(
    conditionalPanel(condition = "input.page_tabs == 'detail_tab'",
                     ns = ns,
                     "This is the module conditional panel visible on detail tab"),
    #conditionalPanel(condition = paste0("input['",ns("checkbox"),"']"),
    conditionalPanel(condition = "input.page_tabs == 'detail_tab'",
                     ns = ns,
                     htmlOutput(ns("selectInput")))
  )
}

condpanel <- function(input, output, session) {

  output$selectInput <- renderUI({

    ns <- session$ns

    selectInput(
      inputId = ns("selectInput"),
      label = "Conditional Input :",
      choices = c("A","B","C")
    )

  })

}

ui <- dashboardPage(skin = "black",
                    title = "Dashboard",
                    dashboardHeader(title="dashboard"),
                    dashboardSidebar(sidebarMenu(id = "sidebar",
                                                 menuItem("Section", tabName = "sectionTab", icon = icon("flask")),
                                                 condpanelUI("foo"),
                                                 conditionalPanel(condition = "input.page_tabs == 'detail_tab'", "This is the top-level conditional panel visible on detail tab"),
                                                 conditionalPanel(condition = "input.page_tabs == 'detail_tab'", htmlOutput("selectInput"))

                    )),
                    dashboardBody(
                      useShinyjs(),
                      tabItems(
                        tabItem(tabName = "sectionTab",
                                tabsetPanel(id = "page_tabs",
                                            tabPanel(
                                              title = "Summary",
                                              value = "summary_tab",
                                              fluidPage(
                                              )),
                                            tabPanel(
                                              title = "Detail",
                                              value = "detail_tab",
                                              fluidPage(
                                              ))
                                            ))))
)

server <- function(input, output, session) {

  output$selectInput <- renderUI({

    selectInput(
      inputId = "selectInput",
      label = "Conditional Input :",
      choices = c("A","B","C")
    )

  })

  callModule(condpanel,"foo")

}

shinyApp(ui, server)

@hlendway. Because your conditionalPanel in condpanelUI is not depended on the input within the module, just remove the ns = ns argument will do.

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

condpanelUI <- function(id) {
    ns <- NS(id)

    tagList(
        conditionalPanel(condition = "input.page_tabs == 'detail_tab'",
                         "This is the module conditional panel visible on detail tab"),
        #conditionalPanel(condition = paste0("input['",ns("checkbox"),"']"),
        conditionalPanel(condition = "input.page_tabs == 'detail_tab'",
                         htmlOutput(ns("selectInput")))
    )
}

condpanel <- function(input, output, session) {

    output$selectInput <- renderUI({

        ns <- session$ns

        selectInput(
            inputId = ns("selectInput"),
            label = "Conditional Input :",
            choices = c("A","B","C")
        )

    })

}

ui <- dashboardPage(skin = "black",
                    title = "Dashboard",
                    dashboardHeader(title="dashboard"),
                    dashboardSidebar(sidebarMenu(id = "sidebar",
                                                 menuItem("Section", tabName = "sectionTab", icon = icon("flask")),
                                                 condpanelUI("foo"),
                                                 conditionalPanel(condition = "input.page_tabs == 'detail_tab'", "This is the top-level conditional panel visible on detail tab"),
                                                 conditionalPanel(condition = "input.page_tabs == 'detail_tab'", htmlOutput("selectInput"))

                    )),
                    dashboardBody(
                        useShinyjs(),
                        tabItems(
                            tabItem(tabName = "sectionTab",
                                    tabsetPanel(id = "page_tabs",
                                                tabPanel(
                                                    title = "Summary",
                                                    value = "summary_tab",
                                                    fluidPage(
                                                    )),
                                                tabPanel(
                                                    title = "Detail",
                                                    value = "detail_tab",
                                                    fluidPage(
                                                    ))
                                    ))))
)

server <- function(input, output, session) {

    output$selectInput <- renderUI({

        selectInput(
            inputId = "selectInput",
            label = "Conditional Input :",
            choices = c("A","B","C")
        )

    })

    callModule(condpanel,"foo")

}

shinyApp(ui, server)
2 Likes

@raytong OK that worked! Thank you for the explanation as well, appreciate the help very much!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.