2

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?

user16024709
  • 151
  • 1
  • 12

2 Answers2

2

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)
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
0

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.

Tomas Capretto
  • 721
  • 5
  • 6
  • Hi. Thank you for your answer. It does align the contents to the right but it does not reduce the width of `select` column. I tried with `list(width = "10%", class = "dt-right", targets = c(0, 1))`. The width of it remains as it is. – user16024709 May 28 '21 at 02:34
  • Looks like @Ronak Shah answer solves your problem – Tomas Capretto May 28 '21 at 11:09