rstudio / DT

R Interface to the jQuery Plug-in DataTables
https://rstudio.github.io/DT/
Other
600 stars 180 forks source link

resizable columns #1037

Open avraam-inside opened 1 year ago

avraam-inside commented 1 year ago

Good afternoon! The DT package is amazing!

But resizable columns are sorely lacking. This is the default parameter, for example, in "reactable" (it's a pity it's not optimized for Shiny).

It is expected that such functionality will also be able to hide part of the cell text through ..., so as not to make ugly large cells with the transferred text.

I found only 1 plugin that does resizable columns, and then it doesn't work correctly. https://stackoverflow.com/questions/72169187/r-shiny-making-datatable-columns-manuallly-resizable

stla commented 1 year ago

Do you see the cursor when you try the plugin?

avraam-inside commented 1 year ago

Using the plugin in R, I see about the same thing as here: http://live.datatables.net/hafazixi/3/edit

That is, even on the example site, this plugin does not work.

There is something similar to a good solution here (it works almost like resizable in reactable): https://stackoverflow.com/questions/67916127/column-resize-for-users-with-dtdatatable, but I do not know how to integrate it into R.

avraam-inside commented 1 year ago

@stla Another important problem with this colResize-plugin is that it doesn't compress column content into ellipsis, as in reactable (or I didn't see it)

avraam-inside commented 1 year ago

For some reason, in all the examples, resizable only works when moving in the header, and I can't move the column at the row level. Why such a restriction is unclear.

resizable is a necessary basis, I do not know how to use DT without it. In reactable, this is integrated with the resizable = TRUE option and works flawlessly.

The lack of such an option is the only thing that stops me from switching to DT.

At the same time, you can't use reactable either, because it doesn't have server-side optimization.

Sadly...

stla commented 1 year ago

Try that:

library(htmltools)
library(DT)

callback <- c(
  "$('table th').resizable({",
  "  handles: 'e',",
  "  stop: function(e, ui) {",
  "    $(this).width(ui.size.width);",
  "  }",
  "});"
)

dtable <- datatable(
  iris, callback = JS(callback),
  options = list(
    ordering = FALSE,
    autoWidth = FALSE,
    dom = "Blfrtip"
  )
)

dep <- htmlDependency("jqueryui", "1.13.2", 
                      src = c(href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2"),
                      script = "jquery-ui.min.js",
                      stylesheet = "themes/base/jquery-ui.min.css")
dtable$dependencies <- c(dtable$dependencies, list(dep))

dtable
stla commented 1 year ago

And this:

library(DT)

callback <- c(
  "$('table th').resizable({",
  "  handles: 'e',",
  "  stop: function(e, ui) {",
  "    $(this).width(ui.size.width);",
  "  }",
  "});"
)

dtable <- datatable(
  iris, callback = JS(callback),
  options = list(
    ordering = FALSE,
    autoWidth = FALSE,
    dom = "Blfrtip"
  )
)

css <- "
.table.dataTable {
  table-layout: fixed;
}
.table.dataTable th {
  white-space: nowrap;
  overflow: hidden;
}
.table.dataTable td {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
"

library(shiny)
ui <- fluidPage(
  tags$head(
    tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"),
    tags$link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/themes/base/jquery-ui.min.css"),
    tags$style(HTML(css))
  ),
  br(),
  DTOutput("tbl")
)
server <- function(input, output, session) {
  output$tbl <- renderDT({
    dtable
  })
}
shinyApp(ui, server)
ulyngs commented 1 year ago

Thank you @stla, this worked for me!!!

Also, I found that in order to get the colResize solution to work, I needed to modify query.dataTables.colResize.css in this way:

table.dataTable thead th.dt-colresizable-hover {
  cursor: col-resize !important;
stla commented 1 year ago

Cool, thanks for posting the solution.