R Shiny Datatable子行选择和信息发布

时间:2019-04-23 17:50:49

标签: r shiny datatables

我在选择带有JS回调的R Shiny DT表中选择子行时遇到问题。

在展开父行时,我尝试选择子行,并在该子行中选择所有行(包括子背景)。 如果我选择第二个子行,则背景被选中,并显示我的两个子行(每隔一次单击将选择所有子行,然后重复显示选中的子行)

此外,如何获取有关选择了哪些子行的信息?

非常感谢! 亚历克斯·B

我正在尝试使用JS回调中的数据表设置。

'''

library(data.table)
library(DT)
library(shiny)
library(jsonlite)

ui <- fluidPage(DT::dataTableOutput(width = "100%", "table"))

server <- function(input, output) {

output$table = DT::renderDataTable({

mtcars_dt = data.table(mtcars)
setkey(mtcars_dt,mpg,cyl)
mpg_dt = unique(mtcars_dt[, list(mpg, cyl)])
setkey(mpg_dt, mpg, cyl)
cyl_dt = unique(mtcars_dt[, list(cyl)])
setkey(cyl_dt, cyl)

mtcars_dt = mtcars_dt[, toJSON(.SD), by = list(mpg,cyl)]
setnames(mtcars_dt,'V1','mtcars')
mtcars_dt[, ' ' := '&#9658;']


df1 = mtcars_dt
df1 = df1[c(1,6),]

setcolorder(df1, c(length(df1),c(1:(length(df1) - 1))))



DT::datatable(
  data = df1,
  rownames = FALSE,
  escape = FALSE,
  selection="multiple",
  options = list(
    # dom = 'Bfrti',
    stripeClasses = list(),
    deferRender = TRUE,
    # scrollX = TRUE,
    pageLength = 25,
    scrollY = "1000",
    scroller = TRUE,
    scollCollapse = TRUE,
    lengthMenu = c(20, 50, 100, 500),
    searchHighlight = TRUE,
    tabIndex = 1,
    columnDefs = list(
      list(orderable = FALSE, className = 'details-control', targets = 0),
      list(visible = FALSE, targets = -1 )
    )
  ),
  callback = JS("

                //table.header().to$().css({'background-color': '#000', 'color': '#fff'})

                table.column(01).nodes().to$().css({cursor: 'pointer'})

                var table_id = 1000

                // Format child object into another table
                var format = function(table_id, columns) {
                if(columns != null){ 

                var result = ('<table id=\"' + table_id + '\"><thead><tr>')
                for (var i in columns){
                result += '<th>' + columns[i] + '</th>'
                }
                result += '</tr></thead></table>'

                return result

                }else{
                return ''
                }
                }

                var format_datatable = function( table_id, newtable, columns) {
                if(newtable != null){


                var column_defs = []

                for (var i in columns)
                {
                if (i == 0)
                {
                column_defs[i] = {'data': columns[i], 'targets': parseInt(i), 'orderable': false, 'className': 'details-control'}
                }

                else
                {
                column_defs[i] = {'data': columns[i], 'targets': parseInt(i)}
                }
                }

                /*    alert(JSON.stringify(column_defs)) */


                //var printTable = document.getElementById(newtable)
                //document.write(newtable)
                //document.write(columns)


                var subtable = $(('table#' + table_id)).DataTable({
                'data': newtable,
                'autoWidth': false, 
                'deferRender': true,
                'stripeClasses': [],
                'info': false, 
                'select': { style: 'os',
                },
                'lengthChange': false, 
                'ordering': false, 
                'paging': false, 
                'scrollX': false, 
                'scrollY': false, 
                'searching': false,
                'columnDefs': column_defs
                }).draw()

                }
                }

                table.on('click', 'td.details-control', function() {

                var td = $(this)
                var table = $(td).closest('table')
                var row = $(table).DataTable().row(td.closest('tr'))


                if (row.child.isShown()) {
                row.child.hide()
                td.html('&#9658;')
                }
                else
                {
                var row_data = row.data()

                if (!Array.isArray(row_data))
                {
                row_data = Object.keys(row_data).map(function (key) {
                return row_data[key]
                });
                }

                var newtable = JSON.parse(row_data[row_data.length-1])
                var columns = Object.keys(newtable[0])

                table_id++

                row.child(format(table_id, columns)).show()
                format_datatable(table_id, newtable, columns)
                console.log(table_id)
                td.html('&#9660;')
                }

                })


                ")
  )
})

observe({
print(input$table_rows_selected)
print(input$newtable_rows_selected)

})

}

shinyApp(ui = ui, server = server)

'''

我想突出显示各个子行,并知道选择了哪些子行。当前,每次点击都会突出显示所有子行。

1 个答案:

答案 0 :(得分:0)

这里是尝试。可以,但是主表上的选择被禁用。

library(data.table)
library(DT)
library(shiny)
library(jsonlite)

initComplete <- paste(
  "function(settings){",
  "  var table = settings.oInstance.api();",
  "  var tbl = table.table().node();",
  "  var id = $(tbl).closest('.dataTable').attr('id');",
  "  table.on('click', 'tbody tr', function(){",
  "    // send selected columns to Shiny",
  "    setTimeout(function(){",
  "      var indexes = table.rows({selected:true}).indexes();",
  "      var indices = Array(indexes.length);",
  "      for(var i = 0; i < indices.length; ++i){",
  "        indices[i] = indexes[i];",
  "      }",
  "      Shiny.setInputValue('childrow_rows_selected', {child: id, rows: indices});",
  "    },0);",
  "  });",
  "}",
  sep = "\n"
)

ui <- fluidPage(DT::dataTableOutput(width = "100%", "table"))

server <- function(input, output) {

  output$table = DT::renderDataTable({

    mtcars_dt = data.table(mtcars)
    setkey(mtcars_dt,mpg,cyl)
    mpg_dt = unique(mtcars_dt[, list(mpg, cyl)])
    setkey(mpg_dt, mpg, cyl)
    cyl_dt = unique(mtcars_dt[, list(cyl)])
    setkey(cyl_dt, cyl)

    mtcars_dt = mtcars_dt[, toJSON(.SD), by = list(mpg,cyl)]
    setnames(mtcars_dt,'V1','mtcars')
    mtcars_dt[, ' ' := '&#9658;']


    df1 = mtcars_dt
    df1 = df1[c(1,6),]

    setcolorder(df1, c(length(df1),c(1:(length(df1) - 1))))

    DT::datatable(
      data = df1,
      rownames = FALSE,
      escape = FALSE,
      selection = "none",
      extensions = "Select",
      options = list(
        # dom = 'Bfrti',
        stripeClasses = list(),
        deferRender = TRUE,
        # scrollX = TRUE,
        pageLength = 25,
        scrollY = "1000",
        scroller = TRUE,
        scollCollapse = TRUE,
        lengthMenu = c(20, 50, 100, 500),
        searchHighlight = TRUE,
        tabIndex = 1,
        columnDefs = list(
          list(orderable = FALSE, className = 'details-control', targets = 0),
          list(visible = FALSE, targets = -1 )
        )
      ),
      callback = JS("

                    table.column(0).nodes().to$().css({cursor: 'pointer'});

                    // var table_id = 1000

                    // Format child object into another table
                    var format = function(table_id, columns) {
                    if(columns != null){ 

                    var result = ('<table id=\"' + table_id + '\"><thead><tr>')
                    for (var i in columns){
                    result += '<th>' + columns[i] + '</th>'
                    }
                    result += '</tr></thead></table>'

                    return result

                    }else{
                    return ''
                    }
                    }

                    var format_datatable = function( table_id, newtable, columns) {
                    if(newtable != null){


                    var column_defs = []

                    for (var i in columns)
                    {
                    if (i == 0)
                    {
                    column_defs[i] = {'data': columns[i], 'targets': parseInt(i), 'orderable': false, 'className': 'details-control'}
                    }

                    else
                    {
                    column_defs[i] = {'data': columns[i], 'targets': parseInt(i)}
                    }
                    }

                    var subtable = $(('table#' + table_id)).DataTable({
                    'data': newtable,",
                    sprintf("initComplete: %s,", initComplete),
"                    'autoWidth': false, 
                    'deferRender': true,
                    'stripeClasses': [],
                    'info': false, 
                    'select': {style: 'multi'},
                    'lengthChange': false, 
                    'ordering': false, 
                    'paging': false, 
                    'scrollX': false, 
                    'scrollY': false, 
                    'searching': false,
                    'columnDefs': column_defs
                    }).draw()

                    }
                    }

                    table.on('click', 'td.details-control', function() {

                    var td = $(this);
                    var table = $(td).closest('table');
                    var row = $(table).DataTable().row(td.closest('tr'));
                    var table_id = 'child' + row.index();

                    if (row.child.isShown()) {
                    row.child.hide();
                    td.html('&#9658;');
                    }
                    else
                    {
                    var row_data = row.data();

                    if (!Array.isArray(row_data))
                    {
                    row_data = Object.keys(row_data).map(function (key) {
                    return row_data[key];
                    });
                    }

                    var newtable = JSON.parse(row_data[row_data.length-1])
                    var columns = Object.keys(newtable[0])

                    //table_id++

                    row.child(format(table_id, columns)).show()
                    format_datatable(table_id, newtable, columns)
                    console.log(table_id)
                    td.html('&#9660;')
                    }

                    })

                    ")
      )
  })

  observe({
#    print(input$table_rows_selected)
#    print(input$newtable_rows_selected)
    print(input$childrow_rows_selected)

  })

  }

shinyApp(ui = ui, server = server)
相关问题