Add child row as nested datatable within exisiting

2019-09-09 16:35发布

问题:

I have a datatable that lists a number of 'stages' (which relate to work employment procedures being carried out against the individual employee).

I have managed to code this so the table can display child rows. I want each child row to display another datatable which will list associated tasks for the selected stage.

So far I have managed to add and display a child row with the table header. See here: [Child Row][1]

My HTML is as follows:

<div class="table-responsive">
<table class="table table-hover " id="stage_datatable">
    <thead>
        <tr>
            <th>Select</th>
            <th><!-- Detail --></th>
            <th>ID</th>
            <th>Stage</th>
            <th>Title</th>
            <th>Desc</th>
            <th>Date/Time</th>
            <th>Location</th>
            <th>Rep Required</th>
            <th>Logged By</th>
            <th>Date Logged</th>
        </tr>
    </thead>                      
</table>           

The Jquery for my stage table is here:

function loadStageTable (action, id) {

$.ajax ( {
    url: './stages/stage_ajax.php',
    method: 'GET',
    data: {action: action, id:id}, // id could be taskID or caseID
    dataType: 'json',
    success: function (data) {
        console.log(data);
        console.log("success");
        iTableCounter = 0;

        var table = $('#stage_datatable').DataTable ( {
            "searching": false,
            "sort": false,
            data:data,
            select: {
                style: 'os'
            },
            responsive: true,
            columns: [
                { 'data': null },
                {
                    "data": null,
                    "className":      'details-control',
                    "orderable":      false,
                    "defaultContent": ''
                },
                { 'data': 'meeting_id' },
                { 'data': 'stage_desc' },
                { 'data': 'meeting_title' },
                { 'data': 'meeting_desc' },
                { 'data': 'meeting_date_time' },
                { 'data': 'meeting_location' },
                { 'data': 'rep_required' },
                { 'data': 'logged_by' },
                { 'data': 'start_date' }
            ],
            "columnDefs": [ {
                "targets": -11,
                "data": null,
                "defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
            }, 
            {
                "targets": -3,
                "className": "dt-body-center",
                "render": function (data, type, full, meta){
                    var is_checked = data == true ? "checked" : "";
                    return '<input type="checkbox" class="checkbox" ' + is_checked + ' disabled />';
                   }
            }]
        }); 
        console.log("stage datatable processed");
        $('#stage_datatable tbody').on('click', 'td.details-control', function () {

            var tr = $(this).parents('tr');
            var row = table.row( tr );

            if ( row.child.isShown() ) { // Close this row if already open
                $('div.slider', row.child()).slideUp( function () {
                    row.child.hide();
                    tr.removeClass('shown');
                } );
            }else {
                // table id is required for child rows and will be unique
                iTableCounter = iTableCounter + 1
                row.child(getChildRow).show(); // call getChildRow function to obtain the child row html

                var caseID = localStorage.getItem('caseID');
                console.log(caseID);
                loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks. THIS DOESN'T WORK
                tr.addClass('shown');
                $('div.slider', row.child()).slideDown("slow");
            }
        });
    },
    failure: function (data) {
        console.log ("failed");
    }
});

In the above I have coded an event that triggers the child row to be inserted:

$('#stage_datatable tbody').on('click', 'td.details-control', function () {

            var tr = $(this).parents('tr');
            var row = table.row( tr );

            if ( row.child.isShown() ) { // Close this row if already open
                $('div.slider', row.child()).slideUp( function () {
                    row.child.hide();
                    tr.removeClass('shown');
                } );
            }else {
                // table id is required for child rows and will be unique
                iTableCounter = iTableCounter + 1
                row.child(getChildRow).show(); // call getChildRow function to obtain the child row html

                var caseID = localStorage.getItem('caseID');
                console.log(caseID);
                loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks
                tr.addClass('shown');
                $('div.slider', row.child()).slideDown("slow");
            }
        });

The getChildRow is as follows:

function getChildRow() {
var x = innerTaskTableTemplate(iTableCounter, taskTableTemplate());
return x;

}

The taskTableTemplate parameter is as follows:

function taskTableTemplate() {
return '<thead>'+
    '<tr>'+
        '<th>Select</th>'+
        '<th>ID</th>'+
        '<th>Task Title</th>'+
        '<th>Desc</th>'+
        '<th>Due Date/Time</th>'+
        '<th>Allocated To</th>'+
        '<th>Logged By</th>'+
        '<th>Date Logged</th>'+
    '</tr>'+
'</thead>'+
    '<tbody></tbody>';

}

And the innerTaskTableTemplate function is as follows:

function innerTaskTableTemplate(tableID, html) {
var sOut = "<div class='slider'><table id='task_table_" + tableID + "'>";
sOut += html;
sOut += "</table></div>";
console.log(sOut);

return sOut;

}

IF I OMIT THIS LINE from my **loadStageTable ** function then the code successfully adds a child row and inserts the table html.

loadMyTaskTable('get case tasks', caseID);

However, if I include the line then the child row seems to disappear. If I inspect the DOM using firebug I can't find my child row (e.g. 'task_table_1'). See [here][2].

The loadMyTaskTable function is as follows:

function loadMyTaskTable (action, id) {

$.ajax ( {
    url: './tasks/task_ajax.php',
    method: 'GET',
    data: {action: action, id:id}, // id could be taskID or caseID
    dataType: 'json',
    success: function (data) {
        console.log(data);
        var taskTable = $('#task_table_1')

        $(taskTable).DataTable ( {
            data:data,
            select: {
                style: 'os'
            },
            responsive: true,
            columns: [
                { 'data': null },
                { 'data': 'task_id' },
                { 'data': 'task_title' },
                { 'data': 'task_desc' },
                { 'data': 'task_due_date' },
                { 'data': 'allocated_to' },
                { 'data': 'logged_by' },
                { 'data': 'start_date' }
            ],
            "columnDefs": [ {
                "targets": -8,
                "data": null,
                "defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
            }]
        }); 
        console.log("task table successfully loaded");  
    },
    failure: function (data) {
        console.log ("failed");
    }
});

}

Please can you let me know where I am going wrong. i am confident that my AJAX is working fine as I've tried adding the task table html onto the main page and it loads properly this way, but not when I dynamically insert it as a child row in my datatable.

I have tried looking at similar other posts (e.g. [click here][3]) but I think that the code has since been superseded by the datatables new API.

Many thanks.

Additional Detail I have debugged the script and found the following:

  1. The script successfully inserts the child row with the task_table_1 html

  2. The child row is subsequently removed from the DOM once it hits the *console.log("task table successfully loaded"); * line in my loadMyTaskTable function.

Am still not sure what I am doing wrong here.