I changed the behavior and fixed some things that can be traced by to DataTables example.
play with this one and see if it is closer to what you want. It assumes a single select. If you pick a row in the child, the parent becomes selected.
http://live.datatables.net/fowiduzi/3/edit
$(document).ready(function () {
var table = $('#example').DataTable({
"data": testdata.data,
select: "single",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": '',
"render": function () {
// Use Font Awesome for the expander in the first cell
return '<i class="fa fa-plus-square" aria-hidden="true"></i>';
},
width: "15px"
},
{ "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');
// get the Font Awesome container
var tdi = tr.find("i.fa");
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tdi.first().removeClass('fa-minus-square');
tdi.first().addClass('fa-plus-square');
}
else {
// check to see if the child row exists.
// dont want to overwrite it if its already there.
if (row.child() && row.child().length > 0) {
row.child.show();
}
else {
// Open this row
row.child(format(row.data())).show();
}
tdi.first().removeClass('fa-plus-square');
tdi.first().addClass('fa-minus-square');
}
});
// Keeps the expander from being selected
table.on("user-select", function (e, dt, type, cell, originalEvent) {
if ($(cell.node()).hasClass("details-control")) {
e.preventDefault();
}
});
// If the parent row gets deselected by the user, deselect any
// selected child rows
table.on("deselect", function (e, dt, type, indexes) {
if (type === 'row') {
var child = dt.row(indexes[0]).child();
if (child && child.length > 0) {
$(child[0]).find(".selected").removeClass("selected");
}
}
});
$("#example").on("click", ".dt-childtable tr", function () {
var tr = $(this).closest("tr");
var childTbl = tr.closest("table");
var parentRow = childTbl.closest("tr").prev();
// see if this row is already selected
var isSelected = tr.hasClass("selected");
// remove previous selects from child table
childTbl.find(".selected").removeClass("selected");
if (isSelected) {
// this is a behavior question do you want the parent row to deselect with
// when the child row is.
//table.rows(parentRow).deselect();
} else {
tr.addClass("selected");
// if the child is selected, make sure the parent is selected but
// don't want to trigger a select event if the row
// is already so check if selected
if (!$(table.row(parentRow).node()).hasClass("selected")) {
table.rows(parentRow).select();
}
}
});
});