1

I have the code shared below. I have multiple tabs one of which has a selectizeInput that contains a list of 50,000 unique values. Hence, as suggested here https://shiny.rstudio.com/articles/selectize.html I use it server side. For some reasons, the page Dashboard 2 that contains the selectizeInput element doesn't react. The field is empty no matter what I type in there. My code is structured using different R files given my really big shiny app. However, in order to replicate the problem, two files are all you need. The first file is called "app.R" and contains the following code:

ui <- dashboardPage( 
  title = "Title test", 
  dashboardHeader(title = "Dashboard header"),
  
  dashboardSidebar(  
    includeCSS("www/styles.css"),
    
    sidebarMenu(
      
     menuItem('Retail1', tabName = "tab1", icon = icon("th"),
              menuItem('Dashboard2', tabName = 'retail_dashboard1')
              ),
      
      menuItem('Retail2', tabName = "tab2", icon = icon("th"),
               menuItem('Dashboard2', tabName = 'retail_dashboard2')
               )
      
    )
  ),
  
  
  
  dashboardBody( 
    
    tabItems(
      
      tabItem(tabName = "retail_dashboard2",
              uiOutput("ui_retail_dashboard2")              )
      
    )
  )
)


server <- function(input, output, session) {    
  
  source("Page_retail_dash2.R", local=T) 
  shiny::updateSelectizeInput(session=session, inputId ='element_with_list_of_cities', choices = rownames(mtcars), server = TRUE )
  
  
}
cat("\nLaunching   'shinyApp' ....")
shinyApp(ui, server)

The second file is called "Page_retail_dash2.R" and contains the following simple code:

output$ui_retail_dashboard3 <- renderUI({ 
  
  tabsetPanel(type = "tabs",
              tabPanel("Dashboard 3",

                       
                       h3("Test"),
                       fluidRow(
                         column(2,
                                selectizeInput(inputId = "element_with_list_of_cities_dash3",
                                               label = "Cities",
                                               choices = NULL, 
                                               selected = NULL,
                                               multiple = TRUE # allow for multiple inputs
                                               ,options = list(create = FALSE, maxOptions = 1000)  # if TRUE, allows newly created inputs))
                                )) 
                       )
              )
  )
})

If you simply copy and paste my code, you should be able to replicate the issue. I also attach here what I see my I run my app.enter image description here You may ask why the first tab is empty. In my app it's not empty, it has some tables but you don't need it in order to replicate this issue.

Angelo
  • 1,594
  • 5
  • 17
  • 50

2 Answers2

1
  1. The tabItems call was missing.
  2. To display more than 1000 choices we need to set something like: selectizeInput(inputId = "myId", label = "myLabel", options = list(maxOptions = 100000L))

Also check my related answer here.

library(shiny)
library(shinydashboard)

ui <- dashboardPage( 
  title = "Dashboard", 
  dashboardHeader(title = "Dashboard"),
  dashboardSidebar(   
    # includeCSS("www/styles.css"),
    sidebarMenu(
      menuItem('Retail', tabName = "dash1", icon = icon("th"),
               menuItem('Dashboard2', tabName = 'retail_dashboard2'),
               menuItem('Dashboard3', tabName = 'retail_dashboard3'),
               menuItem('Dashboard4', tabName = 'retail_dashboard4'),
               menuItem('Dashboard5', tabName = 'retail_dashboard5'),
               menuItem('Dashboard6', tabName = 'retail_dashboard6'),
               menuItem('Dashboard7', tabName = 'retail_dashboard7'),
               menuItem('Dashboard8', tabName = 'retail_dashboard8'),
               menuItem('Dashboard9', tabName = 'retail_dashboard9'),
               menuItem('Dashboard10', tabName = 'retail_dashboard10'),
               menuItem('Dashboard11', tabName = 'retail_dashboard11'),
               menuItem('Dashboard12', tabName = 'retail_dashboard12')
      )
    )
  ),
  dashboardBody( 
    tabItems(
      tabItem(tabName = "retail_dashboard3",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard3_table")))
      ),
      tabItem(tabName = "retail_dashboard4",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard4_table")))
      ),
      tabItem(tabName = "retail_dashboard5",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard5_table")))
      ),
      tabItem(tabName = "retail_dashboard6",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard6_table")))
      ),
      tabItem(tabName = "retail_dashboard7",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard7_table")))
      ),
      tabItem(tabName = "retail_dashboard8",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard8_table")))
      ),
      tabItem(tabName = "retail_dashboard9",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard9_table")))
      ),
      tabItem(tabName = "retail_dashboard10",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard10_table")))
      ),
      tabItem(tabName = "retail_dashboard11",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard11_table")))
      ),
      tabItem(tabName = "retail_dashboard12",
              h3('Text'),
              fluidRow(column(12,
                              dataTableOutput("retail_dashboard12_table")))
      ),
      tabItem(tabName = "retail_dashboard2",
              h3("Test"),
              fluidRow(
                column(2,
                       selectizeInput(inputId = "element_with_list_of_cities",
                                      label = "Cities",
                                      choices = NULL, 
                                      selected = NULL,
                                      multiple = TRUE, # allow for multiple inputs
                                      options = list(create = FALSE, maxOptions = 100000L)  # if TRUE, allows newly created inputs))
                       )) 
              )            
      )
    )
  )
)

server <- function(input, output, session) {    
  output$retail_dashboard3_table <- 
    output$retail_dashboard4_table <- 
    output$retail_dashboard5_table <- 
    output$retail_dashboard6_table <- 
    output$retail_dashboard7_table <- 
    output$retail_dashboard8_table <- 
    output$retail_dashboard9_table <- 
    output$retail_dashboard10_table <- 
    output$retail_dashboard11_table <- 
    output$retail_dashboard12_table <- renderDataTable({return(mtcars)})
  updateSelectizeInput(session=session, inputId ='element_with_list_of_cities', choices = 1:60000, server = TRUE)
}

cat("\nLaunching   'shinyApp' ....")
shinyApp(ui, server)

result

ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • That's a fair point but unfortunately it doesn't solve the problem. I will also attach a screenshot of what I see. I see basically exactly what you shared in your screenshot, but no drop-down box shows up on my end. – Angelo Feb 23 '22 at 13:21
  • @Angelo - than your example code does not reflect the problem. Please try to create a reproducible example. – ismirsehregal Feb 23 '22 at 13:29
  • @Angelo maybe the problem is, that the choices aren't loaded yet when you are trying to access them? – ismirsehregal Feb 23 '22 at 13:32
  • But how come though? As you can see I'm testing the code not with the actual vector (that has 50k + unique values) but simply with rownames(mtcars), so I can't really understand what may cause this problem – Angelo Feb 23 '22 at 14:10
  • @Angelo have you set appropriate `options = list(create = FALSE, maxOptions = 100000L)` to allow so many choices in your `selectizeInput`? Please see my edit – ismirsehregal Feb 23 '22 at 14:17
  • Eventually I probably will, but now I can't even manage to display 4 different values! – Angelo Feb 23 '22 at 14:30
  • Please copy and paste my example. It needs some time to load but it's fully working with 60000 choices. – ismirsehregal Feb 23 '22 at 14:44
  • Just to clarify, are you referring to the code you shared here? https://stackoverflow.com/questions/70618250/how-to-add-a-spinner-before-a-selectizeinput-has-loaded-all-the-choices-shiny/70621460#70621460 – Angelo Feb 23 '22 at 15:03
  • @Angelo - No, I'm referring to my answer given above (see the new screenshot) - that link was just to provide you with some further information. – ismirsehregal Feb 23 '22 at 15:08
  • I actually have a better way for you to (hopefully) replicate the bug. It seems to be due to the fact I use multiple files. Let me edit the description of the bug above and perhaps you'll have a suggestion ! – Angelo Feb 23 '22 at 18:44
  • if you create the two files I mentioned and copy and paste the code, you should be able to replicate the problem. – Angelo Feb 23 '22 at 18:51
  • 1
    @Angelo - after your edit the issue is clear. The problem is using `renderUI`. It is executed only after you first visited the tab. At this point `updateSelectizeInput` already tried to update the not yet existing `selectizeInput`. I won't update my answer again (it is working as it stands) because @YBS already provided a workaround regarding `renderUI`. See [this](https://github.com/rstudio/shiny/issues/3348#issuecomment-810727477) for another workaround. – ismirsehregal Feb 24 '22 at 13:01
  • Thank you for all your help! The solution provided above by YBS has fixed the problem. Appreciated all your support. – Angelo Feb 24 '22 at 13:03
1

That is because you are updating too soon. Your variable is NULL until you go to that tab, and only then you should update. Define a ID in the sidebarMenu, and then updateSelectizeInput when you are in that specific tab. Full code:

ui <- dashboardPage( 
  title = "Title test", 
  dashboardHeader(title = "Dashboard header"),
  
  dashboardSidebar(  
    #includeCSS("www/styles.css"),
    
    sidebarMenu(id="tabs",
      
      menuItem('Retail1', tabName = "tab1", icon = icon("th"),
               menuItem('Dashboard1', tabName = 'retail_dashboard1')
      ),
      
      menuItem('Retail2', tabName = "tab2", icon = icon("th"),
               menuItem('Dashboard2', tabName = 'retail_dashboard2')
      )
      
    )
  ),
  dashboardBody( 
    
    tabItems(
      
      tabItem(tabName = "retail_dashboard2",
              uiOutput("ui_retail_dashboard2")              )
      
    )
  )
)

server <- function(input, output, session) {    
  
  source("Page_retail_dash2.R", local=T)
  # observe({
  #   print(input$element_with_list_of_cities) 
  #   print(input$tabs)
  # })
  observeEvent(input$tabs,{
    if (input$tabs=="retail_dashboard2")  updateSelectizeInput(session=session, inputId ='element_with_list_of_cities', 
                         choices = rownames(mtcars) , selected=rownames(mtcars)[1], server = TRUE )
  })
  
}
#cat("\nLaunching   'shinyApp' ....")
shinyApp(ui, server)

output

Please not that your IDs should match and I have put a dummy selection in Page_retail_dash2.R

output$ui_retail_dashboard2 <- renderUI({ 
  tabsetPanel(type = "tabs",
              tabPanel("My Dashboard",
                       h3("Test"),
                       fluidRow(
                         column(2,
                                selectizeInput(inputId = "element_with_list_of_cities",
                                               label = "Cities",
                                               choices = c("A","B"), 
                                               selected = "A",
                                               multiple = TRUE # allow for multiple inputs
                                               ,options = list(create = FALSE, maxOptions = 10000L)  # if TRUE, allows newly created inputs))
                                )) 
                       )
              )
  )
})
YBS
  • 19,324
  • 2
  • 9
  • 27