shiny icon indicating copy to clipboard operation
shiny copied to clipboard

'selectize-plugin-a11y' is causing 'updateSelectInput()' to break when using a DT with `filter` option

Open daattali opened this issue 3 years ago • 9 comments

Sample code to reproduce using latest dev version of shiny:

library(shiny)

ui <- fluidPage(
  selectInput("test", "test", choices = LETTERS[1:5]),
  actionButton("go", "go"),
  DT::DTOutput("table")
)

server <- function(input, output, session) {
  observeEvent(input$go, {
    updateSelectInput(session, "test", choices = letters[6:10])
  })

  output$table <- DT::renderDT({
    DT::datatable(mtcars, filter = "top")
  })
}

shinyApp(ui, server)

When you click "go" to update the selectInput, it become a plain HTML selectbox (see screenshot below) and a JS error in the console comes up:

image

VM35:2 Uncaught Error: Unable to find "selectize-plugin-a11y" plugin
    at L.a.loadPlugin (<anonymous>:2:4581)
    at L.a.require (<anonymous>:2:4888)
    at L.a.initializePlugins (<anonymous>:2:4450)
    at new L (<anonymous>:2:10781)
    at HTMLSelectElement.<anonymous> (<anonymous>:3:5531)
    at Function.each (jquery.min.js:2)
    at S.fn.init.each (jquery.min.js:2)
    at S.fn.init.a.fn.selectize (<anonymous>:3:5249)
    at exports.InputBinding._selectize (input_binding_select.js:199)
    at exports.InputBinding.receiveMessage (input_binding_select.js:62)

Notes:

  • The problem does not happen if the filter argument of DT is not used. It's possible that other javascript libraries would also break the new selectInput due to similar issues.
  • The problem does not exist in the current CRAN version 1.5.0

daattali avatar Oct 31 '20 08:10 daattali

FWIW, I am still running into this with shiny 1.6. It shows up occasionally, and apparently depending on the sequence with which different parts of the app are rendered. I think the error is reproducible if a data table is rendered prior to a select input being rendered. The error does not appear to show up if a select input is rendered prior to a data table being rendered. I'll try to confirm this and put together a reprex later.

bhogan-mitre avatar Feb 01 '21 15:02 bhogan-mitre

Unfortunately still open. Here is a reprex:

Commenting out either filter option in datatable or selectizeInput will give a correct dateInput, but if not dateinput does not initialize correctly. I took a look at the console in Chrome and it writes uncaught Error: Unable to find "selectize-plugin-a11y" plugin, see below

library(shiny)
library(DT)

ui <- fluidPage(
      actionButton("test","Test"),
      DT::dataTableOutput("dt_table")
)


server <- function(input, output, session) {
   
   
   observeEvent(input$test,
                {
                   shiny::showModal(
                      shiny::modalDialog(
                         shiny::selectizeInput(
                            "idName",
                            label = "variable",
                            choices = c("A","B"),
                            selected = "A",
                            options = list(create = F)
                         ),
                         shiny::dateInput(
                            "idName2",
                            label = "variable2",
                            value = as.Date("1980-01-01")
                         )
                         ,
                         size = "l"
                      )
                   )
                   
                })
   
   output$dt_table <- renderDataTable({
     
      datatable(iris,
                selection = "single"
                ,
                filter="top"
                )
      
      
   })
}

SessionInfo: R version 4.0.3 (2020-10-10) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 17763)

Matrix products: default

locale: [1] LC_COLLATE=German_Germany.1252 LC_CTYPE=German_Germany.1252 LC_MONETARY=German_Germany.1252 LC_NUMERIC=C
[5] LC_TIME=German_Germany.1252

attached base packages: [1] stats graphics grDevices utils datasets methods base

other attached packages: [1] DT_0.17 shiny_1.6.0

loaded via a namespace (and not attached): [1] Rcpp_1.0.5 digest_0.6.25 later_1.1.0.1 mime_0.9 R6_2.4.1 jsonlite_1.7.1 lifecycle_0.2.0 xtable_1.8-4
[9] magrittr_1.5 cachem_1.0.3 rlang_0.4.10 promises_1.1.1 jquerylib_0.1.3 bslib_0.2.4 ellipsis_0.3.1 tools_4.0.3
[17] htmlwidgets_1.5.2 crosstalk_1.1.0.1 yaml_2.2.1 httpuv_1.5.4 fastmap_1.0.1 compiler_4.0.3 htmltools_0.5.1.1 sass_0.3.1

uncaught Error: Unable to find "selectize-plugin-a11y" plugin at L.a.loadPlugin (:2:4581) at L.a.require (:2:4888) at L.a.initializePlugins (:2:4450) at new L (:2:10781) at HTMLSelectElement. (:3:5531) at Function.each (jquery.min.js:2) at S.fn.init.each (jquery.min.js:2) at S.fn.init.a.fn.selectize (:3:5249) at exports.InputBinding._selectize (input_binding_select.js:199) at exports.InputBinding.initialize (input_binding_select.js:148)

danbartl avatar Feb 12 '21 20:02 danbartl

I'm running into the same issue as above and as of now my solution is to either remove "filter" or update all instances of "selectInput" on my app to a different input like "pickerInput". Since my app is rather large, I'm opting to exclude 'filter' instead of updating all the selectInputs and re-working the UI.

jsinnett avatar Jul 08 '21 21:07 jsinnett

Thanks for the reprex @dbart79. It appears your issue is subtly different from @daattali's (which was indeed fixed by #3155). Until we have proper fix for your issue, a workaround is to place the HTML dependencies of selectizeInput() into the UI:

ui <- fluidPage(
  htmltools::findDependencies(selectizeInput("foo", "bar", choices = "a")),
  actionButton("test","Test"),
  DT::dataTableOutput("dt_table")
)

cpsievert avatar Jul 08 '21 22:07 cpsievert

@cpsievert Hello! Is any news about this issue?

kuzmenkov111 avatar Sep 19 '21 22:09 kuzmenkov111

It seems this is a slightly more general problem than what I originally reported. I believe that if a DT::datatable() gets rendered with a filter parameter, then any select inputs that get rendered afterwards cause a javascript error. See below as an example.


library(shiny)

ui <- fluidPage(
  DT::dataTableOutput("table"),
  uiOutput("out")
)

server <- function(input, output, session) {
  output$table <- DT::renderDataTable({
    DT::datatable(cars, filter = "top")
  })

  output$out <- renderUI({
    selectInput("num", "num", 1:5)
  })
}

shinyApp(ui, server)

This results in a javascript error and the input not rendering correctly.

This is a bigger problem than just the input, it affects the entire app afterwards. As you can see in the following example, I cannot dismiss a modal because of this error:

library(shiny)

ui <- fluidPage(
  actionButton("test", "test"),
  DT::dataTableOutput("table")
)

server <- function(input, output, session) {
  output$table <- DT::renderDataTable({
    DT::datatable(cars, filter = "top")
  })

  observeEvent(input$test,{
    showModal(
      modalDialog(
        selectInput("num", "num", 1:5),
        actionButton("dismiss", "Dismiss"),
        footer = NULL
      )
    )
  })
  
  observeEvent(input$dismiss, {
    removeModal()
  })
}

shinyApp(ui, server)

The only workaround I can find right now is forcing the dependency to get added to the UI using htmltools::findDependencies(selectInput("test", "test", NULL)),

daattali avatar Dec 02 '21 21:12 daattali

Not sure if this is helpful but the shinyWidgets::pickerInput still works as expected.

library(shiny)
# library(shinyWidgets)
# library(DT)

shinyApp(
  ui = fluidPage(
    actionButton("test", "test"),
    DT::dataTableOutput("table")
  ),
  
  server = function(input, output, session) {
    output$table <- DT::renderDataTable({
      DT::datatable(cars, filter = "top")
    })
    
    observeEvent(input$test,{
      showModal(
        modalDialog(
          shinyWidgets::pickerInput("num", "num", 1:5),
          actionButton("dismiss", "Dismiss"),
          footer = NULL
        )
      )
    })
    
    observeEvent(input$dismiss, {
      removeModal()
    })
  }
)

matton2 avatar Jan 25 '22 20:01 matton2

Another workaround is setting the argument selectize = FALSE in selectInput

phoward38 avatar Apr 05 '22 17:04 phoward38

Thanks for that workaround phoward38 - simple and worked a treat!!!

Jareem7 avatar Jul 10 '22 04:07 Jareem7

Thanks!, another workaround with images!,

Selectize01 Selectize02

jb4utista avatar Jun 22 '23 21:06 jb4utista

Appears this is fixed now, probably as a result of #3358

cpsievert avatar Nov 22 '23 15:11 cpsievert