change the background color of datatable in shiny

This post was flagged by the community and is temporarily hidden.

Does your question depend on shiny in any way? Yes, you are using it in shiny context, but the question is ultimately about DT::datatable, correct? Can you make it work without shiny, just in RStudio console, for example?

Also, can you provide a reprex with mtcars, for example. It would probably be easier for you and everyone to use built-in dataset instead of subdata

I've worked on a similar issue a little while ago and I had written an example to figure this out. I modified my code to use a somewhat similar dataset. I the colors that you provided in the example.

You can use the option initComplete, but it's bit tricky to select specific columns. Instead, it's far easier to figure out a way to add css classes to each column, and then target define the styles using tags$style(...). The option columnDefs gives you a way to render the data table with custom css class names. Values must be in list format, but we can generate this using lapply. Before we get there, I modified my example to have a similar dataset as yours (but with random data).

# randomize data
set.seed(12345)
rows <- 3
cols <- 7
raw <- matrix(data=rnorm(rows * cols,50,12), nrow = rows, ncol = cols)
df <- data.frame(raw, stringsAsFactors = FALSE)
colheaders <- letters[1:7]
colnames(df) <- colheaders

According to the DT docs, we need a class name and a target (which column to apply the styles to). The format is to wrap a series of lists in a parent list. This can be done using the the lapply function and the object colheaders. See below.

lapply(
    1:length(colheaders),
        function(x){
            list(
                 targets=x,
                 className=paste0("column-", colheaders[x])
            )
       }
)

You can either build this outside of the shiny app or do it inline. Which ever method you choose, make sure the list is referenced in the options list. For example -

DT::datatable(
    data = df,
    options = list(
        lengthMenu = c(5,10,15,20), 
        pageLength = 10,
        scrollX = TRUE,
        columnDefs = lapply(
            1:length(colheaders),
                function(x){
                    list(
                        targets=x,
                        className=paste0("column-", colheaders[x])
                     )
                 }
            )
     ),
     editable = FALSE
)

This will render the table and assign a class name for each column. So column a will have a class of column-a. Column b would be column-b and so forth. You can use any name you like.

Now that the class names are in there, you can target them with css using the tags$style(...) function. Alternatively, you can create a css file and read it using tags$link(...).

tags$head(
    tags$style(
        ".column-a{background-color: pink;}",
        ".column-b{background-color: red;}",
        ".column-c{background-color: green;}",
        ".column-d{background-color: lightblue;}",
        ".column-e{background-color: blue;}",
        ".column-f{background-color: black; color: #f0f0f0}",
        ".column-g{background-color: red;}",
    )  
),

That's about it.

Here's the full example.

# pkgs
library(shiny)
library(DT)

# randomize data
set.seed(12345)
rows <- 3
cols <- 7
raw <- matrix(data=rnorm(rows * cols,50,12), nrow = rows, ncol = cols)
df <- data.frame(raw, stringsAsFactors = FALSE)
colheaders <- letters[1:7]
colnames(df) <- colheaders

# build app
shinyApp(
    ui = tagList(
        
        # head - styles
        tags$head(
            tags$style(
                ".column-a{background-color: pink;}",
                ".column-b{background-color: red;}",
                ".column-c{background-color: green;}",
                ".column-d{background-color: lightblue;}",
                ".column-e{background-color: blue;}",
                ".column-f{background-color: black; color: #f0f0f0}",
                ".column-g{background-color: red;}",
            )  
        ),
        
        # main element
        tags$main(
            DT::dataTableOutput("x1")
        )
    ),
    server = function(input, output){
        output$x1 <- DT::renderDataTable({
            DT::datatable(
                data = df,
                options = list(
                    lengthMenu = c(5,10,15,20), 
                    pageLength = 10,
                    scrollX = TRUE,
                    columnDefs = lapply(
                        1:length(colheaders),
                        function(x){
                            list(
                                targets=x,
                                className=paste0("column-", colheaders[x])
                            )
                        }
                    )
                ),
                editable = FALSE
            )
        })
    }
)

EDITS

I forgot to add the screenshot.

2 Likes

I really appreciate your help,thank you

what if i wanna apply the same color for all columns without any css,is there any way to get this done.

There is a working example in the DT docs. Checkout the Callbacks in Options example. You will have to modify the example slightly to target the desired elements (i.e., header, body, etc.) and colors. There's a full list of available functions in the DT api docs. There's still a bit of css though, but I'm guessing you would like to avoid using tags$style(...).

1 Like

okay,thanks for your help,i will check it out

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.