我在选择带有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[, ' ' := '►']
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('►')
}
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('▼')
}
})
")
)
})
observe({
print(input$table_rows_selected)
print(input$newtable_rows_selected)
})
}
shinyApp(ui = ui, server = server)
'''
我想突出显示各个子行,并知道选择了哪些子行。当前,每次点击都会突出显示所有子行。
答案 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[, ' ' := '►']
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('►');
}
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('▼')
}
})
")
)
})
observe({
# print(input$table_rows_selected)
# print(input$newtable_rows_selected)
print(input$childrow_rows_selected)
})
}
shinyApp(ui = ui, server = server)