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;
}
"))
)
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"
)
)
})
}
)