Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

r shiny - uiOutput not rendering inside menuItem

Question

Why does a sliderInput() that's generated on the server, and rendered on the ui with uiOutput() not get displayed in a menuItem()?

Example

In this simple app I'm generating a sliderInput on the server (note the menuItem is deliberately commented out), and it works as expected

library(shiny)
library(shinydashboard)

rm(ui, server)

ui <- dashboardPage(
    dashboardHeader(),

    dashboardSidebar(
        sidebarMenu(
            #menuItem(text = "data options",
                      checkboxGroupInput(inputId = "cbg_group1", label = "group 1", 
                                         choices = c("some","check","boxes","to","choose","from") ),
                       uiOutput("sli_val1"),
                       checkboxGroupInput(inputId = "cbg_group2", label = "group 2", 
                                          choices = c("another","set","of","check","boxes") ),
            #                ),
            menuItem(text = "another tab")
            )
    ),
    dashboardBody()
)

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

    withProgress(message = "loading page", value=0.1, {
        ## simulate loading some data
        Sys.sleep(3)

        ## slider input
        output$sli_val1 <- renderUI({
            sliderInput(inputId = "sli_val1", 
                        label = "values", min = 0, max = 100,
                        value = c(25, 75) )
        })
        setProgress(value=1, detail="Complete")
    })
}

shinyApp(ui = ui, server = server)

However, when I move the uiOutput inside a menuItem( ), the output no longer renders:

ui <- dashboardPage(
    dashboardHeader(),

    dashboardSidebar(
        sidebarMenu(
            menuItem(text = "data options",
                     checkboxGroupInput(inputId = "cbg_group1", label = "group 1", 
                                        choices = c("some","check","boxes","to","choose","from") ),
                     uiOutput("sli_val1"),
                     checkboxGroupInput(inputId = "cbg_group2", label = "group 2", 
                                        choices = c("another","set","of","check","boxes") )
                             ),
            menuItem(text = "another tab")
            )
    ),
    dashboardBody()
)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

At first, I'd change uiOutput("sli_val1") into uiOutput("out_sli_val1"), to prevent duplicated Ids.

Concerning your problem: This is an odd thing going on when Shiny runs through the document and renders/binds all possible outputs. The default action is to ignore all hidden output elements - that means not ignore completely (output "sli_val1" is bound alright), but their function is suspended, letting no children to be rendered.

So the problem is, that on initiation, this output is hidden in the subitem tree and from there on ignored.

The fix can be done by unsetting this supension behaviour by calling

outputOptions(output, "out_sli_val1", suspendWhenHidden = FALSE)

But how and where? This option has to be set before you run your "data loading". But it will throw errors, if output$out_sli_val1 has nothing assigned to it (is NULL). To avoid that, one can initialize an empty UI-chunk, which gets overridden on "data load".

Here is your minimal fix with 2 extra lines of code (and modified output Id):

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    sidebarMenu(
      menuItem(text = "data options", 
        checkboxGroupInput(inputId = "cbg_group1", label = "group 1", 
                           choices = c("some","check","boxes","to","choose","from") ),
        uiOutput("out_sli_val1"),
        checkboxGroupInput(inputId = "cbg_group2", label = "group 2", 
                           choices = c("another","set","of","check","boxes") )
      ),
      menuItem(text = "another tab")
    )
  ),
  dashboardBody()
)

server <- function(input, output, session){
  output$out_sli_val1 <- renderUI({})
  outputOptions(output, "out_sli_val1", suspendWhenHidden = FALSE)

  withProgress(message = "loading page", value=0.1, {
    ## simulate loading some data
    Sys.sleep(3)

    ## slider input
    output$out_sli_val1 <- renderUI({
      sliderInput(inputId = "sli_val1", label = "values", min = 0, max = 100, value = c(25, 75) )
    })

    setProgress(value=1, detail="Complete")
  })
}

shinyApp(ui = ui, server = server)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...