Я работаю над таблицей данных с дочерними строками (отмечены красным цветом), где можно выбрать только одну (основную) строку, щелкнув (отмечена синим цветом).
Вот функция Javascript, которую я реализовал до сих пор. Может ли кто-нибудь помочь мне с этими проблемами? Заранее большое спасибо!
// Text format of the displayed text in the child row
var format = function( d ) { //
return '<div class=\"child-row-abstract\"> ' + d[5] + '</div>';
};
// Column with index=0 is selectable per mouse
table.column(0).nodes().to$().css({cursor: 'pointer'});
// Open/close child row
table.on('click', 'td.details-control', function() {
var td = $(this);
var row = table.row(td.closest('tr'));
if (!row.child.isShown()) {
row.child(format(row.data())).show();
td.html(", quote(symbol_minus), ");
} else {
row.child.hide();
td.html(", quote(symbol_plus), ");
}
});
Делает ли ваш код что-нибудь, как есть? Выдает ошибку? Нам также нужно увидеть html, чтобы понять, что происходит.
На самом деле, опубликованный код является частью блестящей программы, которая слишком велика, чтобы публиковать ее здесь. Я собираюсь разбить его на работающий пример, а затем опубликовать его.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я знаю, что вы ориентируетесь на приложение Shiny для этого, но вот ванильный подход DataTables, который вы сможете адаптировать к Shiny.
Предотвратите работу выбора/отмены выбора строки, когда пользователь нажимает на первый столбец, содержащий кнопки открытия/закрытия.
Для первого столбца включите выбор строки внутри кода прослушивателя событий открытия/закрытия.
Убедитесь, что вы настроили стиль выбора как 'single'.
Шаг 1:
Это позволяет вам отделить функциональность открытия/закрытия от функциональности выбора/отмены выбора:
table.on( 'user-select', function ( e, dt, type, cell, originalEvent ) {
if ( $(originalEvent.target).index() === 0 ) {
e.preventDefault();
}
} );
Шаг 2:
Добавьте row.select(); в конец кода прослушивателя событий открытия/закрытия.
Шаг 3:
Используйте стиль выделения одной строки.
select: {
style: 'single'
}
Базовая демонстрация:
Примечание: в демо нет значков + (открыть) и - (закрыть) — так что вам нужно их представить и просто щелкнуть по пустым ячейкам в первом столбце.
var dataSet = [{
"id": "123",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
{
"id": "456",
"name": "Donna Snider",
"position": "Customer Support",
"salary": "$112,000",
"start_date": "2011/01/25",
"office": "New York",
"extn": "4226"
},
{
"id": "567",
"name": "Cedric Kelly",
"position": "Senior Javascript Developer",
"salary": "$433,060",
"start_date": "2012/03/29",
"office": "Edinburgh",
"extn": "6224"
},
{
"id": "432",
"name": "Airi Satou",
"position": "Accountant",
"salary": "$162,700",
"start_date": "2008/11/28",
"office": "Tokyo",
"extn": "5407"
},
{
"id": "987",
"name": "Brielle Williamson",
"position": "Integration Specialist",
"salary": "$372,000",
"start_date": "2012/12/02",
"office": "New York",
"extn": "4804"
}
];
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
return '<table class = "cell-border" cellpadding = "5" cellspacing = "0" border = "0" style = "padding-left:50px;">' +
'<tr>' +
'<td>Full name:</td>' +
'<td>' + d.name + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + d.extn + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extra info:</td>' +
'<td>And any further details here (images etc)...</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function() {
var table = $('#example').DataTable({
select: {
style: 'single'
},
data: dataSet,
"columns": [{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "name"
},
{
"data": "position"
},
{
"data": "office"
},
{
"data": "salary"
}
],
"order": [
[1, 'asc']
]
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function() {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
row.select();
});
table
.on('user-select', function(e, dt, type, cell, originalEvent) {
if ($(originalEvent.target).index() === 0) {
e.preventDefault();
}
});
});<!doctype html>
<html>
<head>
<meta charset = "UTF-8">
<title>Demo</title>
<script src = "https://code.jquery.com/jquery-3.5.1.js"></script>
<script src = "https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel = "stylesheet" type = "text/css" href = "https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link href = "https://cdn.datatables.net/select/1.6.2/css/select.dataTables.min.css" rel = "stylesheet" />
<script src = "https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script>
<link rel = "stylesheet" type = "text/css" href = "https://datatables.net/media/css/site-examples.css">
<style>
td.details-control {
background: url('./resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('./resources/details_close.png') no-repeat center center;
}
</style>
</head>
<body>
<div style = "margin: 20px;">
<table id = "example" class = "display dataTable cell-border" style = "width:100%">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
</div>
</body>
</html>Кроме того, убедитесь, что вы включили пакет расширения "Выбрать", например, `DT::datatable(data = df, selection = "none", extensions = c("Buttons", "Select"), options = list( select = list(style = "single", items = "row")), callback = DT::JS(" ... "))' Еще раз большое спасибо!
Нам нужен полный фрагмент, чтобы помочь вам, пожалуйста, создайте его с помощью инструмента
[<>]