rstudio / DT

R Interface to the jQuery Plug-in DataTables
https://rstudio.github.io/DT/
Other
599 stars 180 forks source link

datatable column filters clash with shiny::selectizeInput when invoked first #1112

Open philippleppert opened 10 months ago

philippleppert commented 10 months ago

By filing an issue to this repo, I promise that

I understand that my issue may be closed if I don't fulfill my promises.


Hello everybody,

I have a shiny app in which one modal contains different control widgets like selectizeInput. A second modal contains a datatable with column filters. When I first open the modal with the datatable (with column filters) and then switch to the modal with the control widgets, the class of the selectizeInput is somehow altered. You can see this for example in Chrome, where the dropdown list now has a very basic appearance. But then again, I am also not able to capture the input's value via input$ any longer.

removed_class

This does not happen if:

normal_class

I am using DT_0.29 and shiny_1.7.5. Edit: just installed DT_0.31 and the problem persists.

Reprex is below:

library(shiny)
library(DT)

ui <- fluidPage(
  # uncomment below
  #selectizeInput("main", "Main", choices= levels(iris$Species)),
  actionButton("modal_pop1", "show modal with selectizeInput"),
  actionButton("modal_pop2", "show modal with datatable with column filter")
)

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

  # modal containing selectizeInput
  observeEvent(input$modal_pop1, ignoreInit = T, {
    showModal(
      modalDialog(
        selectizeInput(
          "select_project", 
          label = "Select something",
          choices = c("...", "A", "B", "C"),
          selected = "...", width = "100%"
        ),
        selectizeInput(
          "edit_pstatus", 
          label = "Select something else",
          choices = c("...", "A", "B", "C"), width = "100%"
        ),
        textAreaInput(
          "edit_pcomment", label = "Tell me something more", 
          value = "", width = "100%"
        ),
        easyClose = T
      )
    )
  })

  # modal containing datatable with column filters
  observeEvent(input$modal_pop2, ignoreInit = T, {
    showModal(
      modalDialog(
        DTOutput("dt_with_col_filter"),
        easyClose = T
      )
    )
  })

  # datatable with column filters inside modal
  output$dt_with_col_filter <- renderDT(server = T, {

    datatable(
      iris,
      style = "bootstrap", class = "row-border",
      rownames = F,
      escape = F,
      selection = 'none',
      # column filters seem to affect other selectizeInputs
      # column filters
      filter = list(position = "top"),
      # placeholders
      callback = JS(c(
        '$(\'td[data-type="character"] div.has-feedback input[type="search"]\').attr( "placeholder", "" )',
        '$(\'td[data-type="factor"] div.has-feedback input[type="search"]\').attr( "placeholder", "All" )'
      )),
      options = list(
        dom = "Btp",
        ordering = F
      )
    )
      })

}

shinyApp(ui, server)

Output of xfun::session_info('DT')

R version 4.3.2 (2023-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 11 (bullseye), RStudio 2023.6.2.561.5

Locale:
  LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C               LC_TIME=de_DE.UTF-8        LC_COLLATE=de_DE.UTF-8    
  LC_MONETARY=de_DE.UTF-8    LC_MESSAGES=de_DE.UTF-8    LC_PAPER=de_DE.UTF-8       LC_NAME=C                 
  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

time zone: Europe/Berlin
tzcode source: system (glibc)

Package version:
  base64enc_0.1.3   bslib_0.5.1       cachem_1.0.8      cli_3.6.1         crosstalk_1.2.0   digest_0.6.33    
  DT_0.29           ellipsis_0.3.2    evaluate_0.21     fastmap_1.1.1     fontawesome_0.5.2 fs_1.6.3         
  glue_1.6.2        graphics_4.3.2    grDevices_4.3.2   highr_0.10        htmltools_0.5.6   htmlwidgets_1.6.2
  httpuv_1.6.11     jquerylib_0.1.4   jsonlite_1.8.7    knitr_1.44        later_1.3.1       lazyeval_0.2.2   
  lifecycle_1.0.3   magrittr_2.0.3    memoise_2.0.1     methods_4.3.2     mime_0.12         promises_1.2.1   
  R6_2.5.1          rappdirs_0.3.3    Rcpp_1.0.11       rlang_1.1.1       rmarkdown_2.25    sass_0.4.7       
  stats_4.3.2       stringi_1.7.12    stringr_1.5.0     tinytex_0.46      tools_4.3.2       utils_4.3.2      
  vctrs_0.6.3       xfun_0.40         yaml_2.3.7  
yihui commented 10 months ago

Thanks for the report! This is most likely to be due to DT using an older version of selectize.js but shiny using a much newer version. I'm not sure if upgrading selectize.js in DT would fix the issue. Upgrading a JS library from 9 years ago may not be a trivial task...

philippleppert commented 10 months ago

Thank You for pointing this out @yihui! I just realized that there was an error logged to my browser's console... Unbenannt

This error now led my to this issue in the shiny package, which was ultimately resolved by upgrading selectize.js. https://github.com/rstudio/shiny/issues/3125

philippleppert commented 10 months ago

Placing the HTML dependencies of selectizeInput() into the UI is also a possible workaround for this issue.

ui <- fluidPage(
  htmltools::findDependencies(selectizeInput("foo", "bar", choices = "a")),
  actionButton("modal_pop1", "show modal with selectizeInput"),
  actionButton("modal_pop2", "show modal with datatable with column filter")
)
yihui commented 9 months ago

Thanks for posting the workaround!