Search code examples
rshinydatatabledt

R Shiny DT datatable how can I change the selected class


Is there a way to change the class of the selected row/column/cell without having to use the "Select" extension?

The problem: when style = "bootstrap" is set, the class for the selected item is class = "active". Because bootstrap themes usually set active to some sort of grey, DT must override bootstrap's active background color so it's not confused with the white/grey alternating row colors. Instead of overriding the color, I want to change the class from active to info. This way, any theme I choose will look nice and the selected row will not be confused with the not-selected rows.

Additionally, the blue that DT chose to override bootstrap's active background color makes the highlight of search terms look hideous. See the example. And the blue that DT chose for the style="default" does not always look good with the selected bootstrap theme.

BTW, I successfully changed the selected class to info using the "Select" extension and setting it in the options, but that presented other problems, mainly that I could not pre-select a row.

library(shiny)
library(DT)

dt <- data.frame(colA = sample(c("one","two"),10,replace=T), ColB = rnorm(10))

ui <- basicPage(
  DTOutput("test_table")
)

server <- function(input, output) {
  
  output$test_table <- renderDT({
    datatable(dt,
      style = "bootstrap",
      selection = list(mode = "single", selected = 1),
      options = list(searchHighlight = T, search = list(search = "o"))
    )
  })
}

shinyApp(ui = ui, server = server)

Solution

  • Here is a solution that tries to avoid dependencies on html/css structure written by DT package, which can change without notice. It uses bs_add_rules() to assign the theme's color to the variable --dt-row-selected. This solution works on bslib 0.6.1 and DT 0.32.

    library(shiny)
    library(DT)
    
    ui <- fluidPage(
      theme = bslib::bs_theme(bootswatch = "superhero") |>
        bslib::bs_add_rules("
        :root {
          --dt-row-selected: var(--bs-primary-rgb)!important;
        }"),
      DTOutput("test_table")
    )
    
    server <- function(input, output) {
      output$test_table <- renderDT({
        datatable(
          iris,
          selection = list(mode = "single", selected = 2)
        )
      })
    }
    
    shinyApp(ui = ui, server = server)