rshinydt

Shinyselected row in a striped DT::datatable() disappears when style = "bootstrap5" and RowGroup extension is used


In a shiny app, selected rows of a striped DT::datatable() are disappearing whenever style = "bootstrap5" and the RowGroup Extension is used. Interestingly enough, only even-numbered rows in the first group are affected.

I tried to resolve this by setting custom CSS, but haven't had any success. Does anybody more knowledgeable have any idea how this could be fixed?

Here is an example to reproduce the issue.

library(bslib)
library(DT)
library(shiny)

shiny::shinyApp(
  ui = shiny::fluidPage(
    DT::DTOutput("table"),
    shiny::verbatimTextOutput("rows_selected")
  ),
  server = function(server, input, output) {
    df <- data.frame(
      "group" = c(rep(1, 5), rep(2, 5)),
      "A" = 1:10,
      "B" = 11:20,
      "C" = LETTERS[1:10]
    )
    output$rows_selected <- shiny::renderText({
      paste("row selection info", input$table_rows_selected)
    })
    output$table <- DT::renderDT({
      DT::datatable(
        data = df,
        style = "bootstrap5",
        class = "stripe",
        rownames = FALSE,
        selection = "single",
        extensions = c("RowGroup"),
        options = list(
          rowGroup = list(dataSrc = 0),
          dom = "tfrBip"
        )
      )
    })
  }
)

Here is my session info:

R version 4.4.1 (2024-06-14 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 22631), RStudio 2024.9.0.375

Locale:
  LC_COLLATE=German_Germany.utf8  LC_CTYPE=German_Germany.utf8    LC_MONETARY=German_Germany.utf8
  LC_NUMERIC=C                    LC_TIME=German_Germany.utf8    

Package version:
  base64enc_0.1.3     bslib_0.9.0         cachem_1.1.0        cli_3.6.3           commonmark_1.9.2   
  compiler_4.4.1      crayon_1.5.3        crosstalk_1.2.1     digest_0.6.37       DT_0.33            
  evaluate_1.0.3      fastmap_1.2.0       fontawesome_0.5.3   fs_1.6.5            glue_1.8.0         
  graphics_4.4.1      grDevices_4.4.1     highr_0.11          htmltools_0.5.8.1   htmlwidgets_1.6.4  
  httpuv_1.6.15       jquerylib_0.1.4     jsonlite_1.8.9      knitr_1.49          later_1.4.1        
  lazyeval_0.2.2      lifecycle_1.0.4     magrittr_2.0.3      memoise_2.0.1       methods_4.4.1      
  mime_0.12           promises_1.3.2      R6_2.5.1            rappdirs_0.3.3      Rcpp_1.0.14        
  rlang_1.1.5         rmarkdown_2.29      rstudioapi_0.17.1   sass_0.4.9          shiny_1.10.0       
  sourcetools_0.1.7.1 stats_4.4.1         tinytex_0.54        tools_4.4.1         utils_4.4.1        
  withr_3.0.2         xfun_0.50           xtable_1.8-4        yaml_2.3.10    

I tried to select an even-numbered row in the first group in the example above and it disappears instead of being highlighted like other rows.

EDIT: Thanks to Phil I was able to figure out a solution. For some reason only the elements of even rows in the first group are equipped with the following CSS from dataTables.bootstrap5.min.css

table.dataTable.table-striped>tbody>tr:nth-of-type(2n+1)>* {
    box-shadow: none
}

which overrides the box-shadow attribute of

table.dataTable>tbody>tr.selected>* {
    box-shadow: inset 0 0 0 9999px rgb(var(--dt-row-selected));
    color: rgb(var(--dt-row-selected-text))
    ..
}

responsible for the default highlighting bevhaviour. This can be solved by adding the !important attribute to the default values tr.selected class

tags$head(
  tags$style(type = "text/css", HTML("
      table.dataTable>tbody>tr.selected>* {
        box-shadow: inset 0 0 0 9999px rgb(var(--dt-row-selected)) !important;
      }
  "))
)

Solution

  • With F12 I have on the first non grouped row:

    table.dataTable.table-striped > tbody > tr.odd > * {
      box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.05);
    }
    

    from dt-core-bootstrap5-1.13.6/css/dataTables.bootstrap5.min.css.

    When I uncheck the css the row come back like before.

    Therefore I try :

    table.dataTable.table-striped > tbody > tr.odd > * {
      box-shadow: initial !important;
    }
    

    Your source with the new css:

    library(bslib)
    library(DT)
    library(shiny)
    
    shiny::shinyApp(
      ui = shiny::fluidPage(
        tags$head(
          tags$style(type = "text/css", HTML("
            table.dataTable.table-striped > tbody > tr.odd > * {
              box-shadow: initial !important;
            }
          "
          ))
        ),  
        DT::DTOutput("table"),
        shiny::verbatimTextOutput("rows_selected")
      ),
      server = function(server, input, output) {
        df <- data.frame(
          "group" = c(rep(1, 5), rep(2, 5)),
          "A" = 1:10,
          "B" = 11:20,
          "C" = LETTERS[1:10]
        )
        output$rows_selected <- shiny::renderText({
          paste("row selection info", input$table_rows_selected)
        })
        output$table <- DT::renderDT({
          DT::datatable(
            data = df,
            style = "bootstrap5",
            class = "stripe",
            rownames = FALSE,
            selection = "single",
            extensions = c("RowGroup"),
            options = list(
              rowGroup = list(dataSrc = 0),
              dom = "tfrBip"
            )
          )
        })
      }
    )