Sortable Tables
The datatable widget is a powerful table-building tool used to display data in shiny apps. It can use many of the datatable plugins and extensions but a small javascript hack is needed for the rowReorder extension which allows rows to be reordered using drag and drop.
In the example below, the rowReorder options are set to selector = 'tr' (select by clicking anywhere on a row) and update = FALSE (do not fire an update to rowReorder). The removal of the update is due to the fact that the rows are not reordered properly in a shiny app. We can now use the row-order event which is fired irrespective of the setting of the update option (row-reordered, however, is only fired when update = true). The javascript function called on row-reorder simply grabs the new order of the table rows and exports it to a shiny variable. This can then be used to update the table.
1library(shiny)
2library(DT)
3
4## Sortable table
5
6server <- function(input, output) {
7
8 df <- reactiveValues(data = mtcars[c(1:20), c('mpg', 'cyl', 'disp')],
9 data_reordered = mtcars[c(1:20), c('mpg', 'cyl', 'disp')])
10
11 output$tab1 <- DT::renderDataTable({
12 DT::datatable(df$data,
13 selection = 'none',
14 extensions = c('Scroller', 'RowReorder'),
15 options = list(rowReorder = list(selector = 'tr', update = FALSE),
16 columnDefs = list(list(targets = 0, visible = TRUE)),
17 deferRender = TRUE,
18 scrollY = 400,
19 scroller = TRUE,
20 dom = 't'),
21 callback = JS("table.on('row-reorder', function(e, diff, edit) {
22 var arr = [];
23 $(this).parent().find('.dataTable tbody tr').each(function() { arr.push($(this).find('td').eq(0).text()); })
24 Shiny.onInputChange('tableReordered', arr);
25 });")
26 )
27 })
28
29 observeEvent(input$tableReordered, {
30 df$data_reordered <- df$data[order(match(row.names(df$data), input$tableReordered)), ]
31 df$order <- input$tableReordered
32 })
33
34 output$df_original <- renderTable(df$data, rownames = TRUE)
35 output$df_reordered <- renderTable(df$data_reordered, rownames = TRUE)
36}
37
38ui <- fluidPage(
39 column(4,
40 h4('Sortable Table'),
41 DT::dataTableOutput('tab1')
42 ),
43 column(4,
44 h4('Original Table'),
45 tableOutput('df_original')
46 ),
47 column(4,
48 h4('Sorted Table'),
49 tableOutput('df_reordered')
50 )
51)
52
53shinyApp(ui = ui, server = server)
54