How to adjust the width of selected columns in datatable (DT)

Viewed 211

I am trying to adjust the width of datatable DT in shiny which works for the below simple example -

library(magrittr)
library(shiny)
library(DT)

ui <- fluidPage(
  DT::dataTableOutput('dt')
)

server <- function(input, output) {
  output$dt <- DT::renderDataTable({
    dt1 <- head(mtcars)
    
    DT::datatable(dt1, rownames = FALSE) %>% 
      DT::formatStyle(columns = c(3,6), width='200px')
  })
}

shinyApp(ui, server)

enter image description here

However, my actual datatable is bit complicated and has some javascript functions.

ui <- fluidPage(
  DT::dataTableOutput('dt', width = '700px')
)

server <- function(input, output) {
  shinyInput = function(FUN, len, id, ...) {
    inputs = character(len)
    for (i in seq_len(len)) {
      inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...))
    }
    inputs
  }
  
  output$dt<- DT::renderDataTable({
    dt1 <- head(mtcars)
    df <- cbind(select = shinyInput(shiny::checkboxInput, nrow(dt1), 'check'),dt1)
    
    DT::datatable(df, selection = 'none', escape = FALSE,options = list(
      preDrawCallback = htmlwidgets::JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
      drawCallback = htmlwidgets::JS('function() { Shiny.bindAll(this.api().table().node()); } '))) %>%
      DT::formatStyle(columns = c(3,6), width='200px')
  })
}

shinyApp(ui, server)

I copied the shinyInput function from this post.

But now formatStyle does not work on this and no width is changed. I want to give different width to every column manually especially reduce the width of the first column with checkbox (select) which takes up lot of space.

enter image description here

Do you have any idea how can I do this?

2 Answers

You can pass width value to shiny::checkboxInput :

df <- cbind(select = shinyInput(shiny::checkboxInput, nrow(dt1), 'check', width = '10px'),dt1)

enter image description here

Complete app code -

ui <- fluidPage(
  DT::dataTableOutput('dt', width = '700px')
)

server <- function(input, output) {
  shinyInput = function(FUN, len, id, ...) {
    inputs = character(len)
    for (i in seq_len(len)) {
      inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...))
    }
    inputs
  }
  
  output$dt<- DT::renderDataTable({
    dt1 <- head(mtcars)
    df <- cbind(select = shinyInput(shiny::checkboxInput, nrow(dt1), 'check', width = '10px'),dt1)
    
    DT::datatable(df, selection = 'none', escape = FALSE,options = list(
      preDrawCallback = htmlwidgets::JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
      drawCallback = htmlwidgets::JS('function() { Shiny.bindAll(this.api().table().node()); } '))) %>%
      DT::formatStyle(columns = c(3,6), width='200px')
  })
}

shinyApp(ui, server)

The following is taken from one of my apps, hope it helps

DT::datatable(
  data = data,
  options = list(
    columnDefs = list(
      list(width = "10%", class = "dt-right", targets = 4)
    )
  )
)

The thing is that you can pass options as a list in columnDefs. That particular option is saying that the fifth column (index starts in 0) has class dt-right (to right-align the content) and its width is 10% of the table. You can pass a vector with more than one element in targets.

Related