DT icon indicating copy to clipboard operation
DT copied to clipboard

Using options > language breaks "DT-radio example"

Open phileas-condemine opened this issue 5 years ago • 1 comments

I tried to make a slight change to the example app of @yihui https://yihui.shinyapps.io/DT-radio/ to add the language option from url ('//cdn.datatables.net/plug-ins/1.10.11/i18n/French.json') in renderDataTable, but the app no longer returned the months radio input. More details in the related question on SO : https://stackoverflow.com/questions/56780937/r-shiny-dt-with-radio-buttons-breaks-when-adding-language-option Someone found a trick to make it work by moving the Shiny.unbindAll & Shiny.bindAll in the initComplete script rather that in the callback.

Here is the code that doesn't work (simply adding the language option)

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput('foo'),
    verbatimTextOutput('sel')
  ),
  server = function(input, output, session) {
    m = matrix(
      as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE,
      dimnames = list(month.abb, LETTERS[1:5])
    )
    for (i in seq_len(nrow(m))) {
      m[i, ] = sprintf(
        '<input type="radio" name="%s" value="%s"/>',
        month.abb[i], m[i, ]
      )
    }
    m
    output$foo = DT::renderDataTable(
      m, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 'tirp', paging = FALSE, ordering = FALSE
                     ,language = list(url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/French.json')
                     ),
      callback = JS("table.rows().every(function(i, tab, row) {
          var $this = $(this.node());
          $this.attr('id', this.data()[0]);
          $this.addClass('shiny-input-radiogroup');
        });
        Shiny.unbindAll(table.table().node());
        Shiny.bindAll(table.table().node());")
    )
    output$sel = renderPrint({
      str(sapply(month.abb, function(i) input[[i]]))
    })
  }
)

Here is my session_info()



    sessioninfo::session_info() - Session info ------------------------------------------------------------------ setting value
    version R version 3.6.0 (2019-04-26) os Windows 10 x64
    system x86_64, mingw32
    ui RStudio
    language (EN)
    collate French_France.1252
    ctype French_France.1252
    tz Europe/Paris
    date 2019-06-26

        Packages ---------------------------------------------------------------------- package * version date lib source
        assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0)
        cli 1.1.0 2019-03-19 [1] CRAN (R 3.6.0)
        crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0)
        crosstalk 1.0.0 2016-12-21 [1] CRAN (R 3.6.0)
        digest 0.6.19 2019-05-20 [1] CRAN (R 3.6.0)
        DT * 0.7.1 2019-06-26 [1] Github (rstudio/DT@c6fd864) htmltools 0.3.6 2017-04-28 [1] CRAN (R 3.6.0)
        htmlwidgets 1.3 2018-09-30 [1] CRAN (R 3.6.0)
        httpuv 1.5.1 2019-04-05 [1] CRAN (R 3.6.0)
        jsonlite 1.6 2018-12-07 [1] CRAN (R 3.6.0)
        later 0.8.0 2019-02-11 [1] CRAN (R 3.6.0)
        magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.0)
        mime 0.7 2019-06-11 [1] CRAN (R 3.6.0)
        packrat 0.5.0 2018-11-14 [1] CRAN (R 3.6.0)
        promises 1.0.1 2018-04-13 [1] CRAN (R 3.6.0)
        R6 2.4.0 2019-02-14 [1] CRAN (R 3.6.0)
        Rcpp 1.0.1 2019-03-17 [1] CRAN (R 3.6.0)
        rlang 0.3.4 2019-04-07 [1] CRAN (R 3.6.0)
        rstudioapi 0.10 2019-03-19 [1] CRAN (R 3.6.0)
        sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0)
        shiny * 1.3.2 2019-04-22 [1] CRAN (R 3.6.0)
        sourcetools 0.1.7 2018-04-25 [1] CRAN (R 3.6.0)
        withr 2.1.2 2018-03-15 [1] CRAN (R 3.6.0)
        xtable 1.8-4 2019-04-21 [1] CRAN (R 3.6.0)
        yaml 2.2.0 2018-07-25 [1] CRAN (R 3.6.0)

Here is the fix (need to change ouput$foo only)

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput('foo'),
    verbatimTextOutput('sel')
  ),
  server = function(input, output, session) {
    m = matrix(
      as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE,
      dimnames = list(month.abb, LETTERS[1:5])
    )
    for (i in seq_len(nrow(m))) {
      m[i, ] = sprintf(
        '<input type="radio" name="%s" value="%s"/>',
        month.abb[i], m[i, ]
      )
    }
    m
    output$foo = DT::renderDataTable(
      m, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 'tirp', paging = FALSE, ordering = FALSE,
                     initComplete = JS("function(settings,json){
                                     var table = settings.oInstance.api();
                                     Shiny.unbindAll(table.table().node());
                                     Shiny.bindAll(table.table().node());}")
                     ,language = list(url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/French.json')
      ),
      callback = JS("table.rows().every(function(i, tab, row) {
                  var $this = $(this.node());
                  $this.attr('id', this.data()[0]);
                  $this.addClass('shiny-input-radiogroup');
                });")
    )
    output$sel = renderPrint({
      str(sapply(month.abb, function(i) input[[i]]))
    })
  }
)


By filing an issue to this repo, I promise that

  • [X] I have fully read the issue guide at https://yihui.name/issue/.
  • [X] I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('DT'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('rstudio/DT').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

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

phileas-condemine avatar Jun 28 '19 08:06 phileas-condemine

Thanks for the reporting. I think the reason is documented in language.url. So yes, you need to provide the callback in options = list(initComplete = #your callback#).

Note that when this parameter is set, DataTables' initialisation will be asynchronous due to the Ajax data load. That is to say that the table will not be drawn until the Ajax request as completed. As such, any actions that require the table to have completed its initialisation should be placed into the initComplete callback.

I planed to update the example using your solution (or document this) but what surprise me is that your solution won't work if this line (,language = list(url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/French.json')) gets removed.

I'll come back later.

shrektan avatar Feb 15 '20 18:02 shrektan