Ajax response count is 0 even though there are results?
Ajax response count is 0 even though there are results?
I am using ajax to populate my child rows. Not all parent rows have child rows. I would like to remove the details-control from the parent if there are no child rows. The child rows show correctly under each parent, but when I alert the number of child rows returned, it always says 0, even when there are some. Why does it do that, and how can I get it to count correctly?
Link to test case:
https://www.ltcsolution.net/TestSite/tammytest4.cfm
var childEditors = {}; // Globally track created child editors
var childTableLevel2; // a level 2 childtable
$(document).ready(function () //do following code after the page loads
{
// creates a level 2 childtable
function formatChild2(rowData) {
var childTableLevel2 = '<table id="cl' + rowData.ID + '" class="display compact nowrap w-100" width="100%" + style="padding-left:20px; width:100%;">' +
'<thead style="display:none"></thead >' +
'</table>';
return $(childTableLevel2).toArray();
}
function sub_DataTable2(mainTableRowID) {
// data for level 2 child
childTableLevel2 = $('#cl' + mainTableRowID).DataTable({
dom: "t",
Language: {ZeroRecords: 'No matching records found'},
ajax: {
url: 'tammytest4-1.cfm?level=2&parent='+mainTableRowID,
dataSrc: '',
data: function(d) {
d.ParentRef = mainTableRowID;
},
},
columns: [ //columns to be returned
{
className: 'details-control1',
orderable: false,
data: null,
defaultContent: ''
},
{data: 'ParentRef'},
{data: 'Type'},
{data: 'ID'},
{data: 'Name'},
{data: 'Dept'},
{data: 'Level'},
{data: 'Department'}
],
select: false
});
//alert shows 0 child rows even if there are child rows
alert(childTableLevel2.data().count());
if (childTableLevel2.data().count() === 0)
{ //always alerts this even if there are child rows
alert("empty table");
}
else
{
alert("has rows");
}
} // end function sub_DataTable2
// Main table
var table = $('#example').DataTable({
dom: 't',
processing: true, //put processing gif on page while loading
//ServerSide: true, //perform actions on server instead of client
StateSave: true, //save sorting, etc so don't have to redo during same session
deferRender: true,
lengthMenu: [ 10, 15, 25, 50, 75, 100 ], //to change the number of records can show in the show entries drop-down
scrollY: '550px',
scrollX: '550px',
Sorting: [4,'asc'],
//Language: {ZeroRecords: 'No matching records found'},
ajax: { //ajax request
url: 'tammytest4-1.cfm?level=1',
dataSrc: '',
},
columns: [ //columns to be returned
{ //creates clickable icon to open and close the list of subaccounts
className: 'details-control',
orderable: false,
data: null,
defaultContent: ''
},
{data: 'ParentRef'},
{data: 'Type'},
{data: 'ID'},
{data: 'Name'},
{data: 'Dept'},
{data: 'Level'},
{data: 'Department'}
],
select: {
style: 'single',
selector: 'td:not(:first-child)'
},
});// end main datatable options
// Add event listener for opening and closing main level childdetails
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
var rowData = row.data();
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
// Destroy the Child Datatable
$('#cl' + rowData.ID).DataTable().destroy();
}
else {
// Open this row
row.child(formatChild2(rowData)).show(); // function to create table
tr.addClass('shown');
var id = rowData.ID;
sub_DataTable2(id); // get info to fill child table
// always alerts empty
/* if ( ! childTableLevel2.data().count() ) {
alert( 'Empty table' );
}
else{
alert('has data');
}*/
}
});
});
<div class="row row-padding">
<div class="col-12">
<div class="card">
<div class="card-body" style="min-width:1000px">
<table id="example" class="display compact nowrap w-100" style="min-width:1000px">
<thead>
<tr>
<th> </th>
<th>ParentRef</th>
<th>Type</th>
<th>ID</th>
<th>Name</th>
<th>Dept</th>
<th>Level</th>
<th>Department</th>
</tr>
</thead>
<tfoot>
<tr>
<th> </th>
<th>ParentRef</th>
<th>Type</th>
<th>ID</th>
<th>Name</th>
<th>Dept</th>
<th>Level</th>
<th>Department</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
[{"Name":"Accounting Services","Level":1,"ID":60,"ParentRef":59,"Department":"Administrative","Type":"Expense","Dept":2},
{"Name":"Accounts Payable","Level":1,"ID":22,"ParentRef":21,"Department":"Administrative","Type":"Accounts Payable","Dept":2},
{"Name":"Accounts Receivable","Level":1,"ID":6,"ParentRef":5,"Department":"Administrative","Type":"Accounts Receivable","Dept":2},
{"Name":"Accumulated Amortization","Level":1,"ID":12,"ParentRef":11,"Department":"Administrative","Type":"Fixed Asset","Dept":2},
{"Name":"Accumulated Amortization","Level":1,"ID":10604,"ParentRef":10603,"Department":"Corporate","Type":"Fixed Asset","Dept":10},
{"Name":"Accumulated Depreciation","Level":1,"ID":14,"ParentRef":13,"Department":"Administrative","Type":"Fixed Asset","Dept":2},
{"Name":"Accumulated Depreciation","Level":1,"ID":10606,"ParentRef":10605,"Department":"Corporate","Type":"Fixed Asset","Dept":10},
{"Name":"Activity Expense","Level":1,"ID":152,"ParentRef":151,"Department":"Activities","Type":"Expense","Dept":1},
{"Name":"Advertising","Level":1,"ID":10444,"ParentRef":10443,"Department":"Administrative","Type":"Expense","Dept":2}];
//ajax response when click on details for Advertising
[{"Name":"Billboards","Level":2,"ID":10445,"ParentRef":10444,"Department":"Administrative","Type":"Expense","Dept":2},
{"Name":"Miscellaneous","Level":2,"ID":10529,"ParentRef":10444,"Department":"Administrative","Type":"Expense","Dept":2},
{"Name":"Newspaper","Level":2,"ID":10448,"ParentRef":10444,"Department":"Administrative","Type":"Expense","Dept":2},
{"Name":"Radio","Level":2,"ID":10450,"ParentRef":10444,"Department":"Administrative","Type":"Expense","Dept":2},
{"Name":"Television","Level":2,"ID":10446,"ParentRef":10444,"Department":"Administrative","Type":"Expense","Dept":2}];
This question has accepted answers - jump to:
Answers
Ajax is an async process. Your row count statements are executed before the Ajax response and Datatables initialization is complete. You need to move your code, the alerts, into a callback that runs after the Ajax response has been processed. Use the
initComplete
option or theinit
event to perform the row count calculations.Kevin
This works perfectly! Thank you!
How do I mark this as answered?
The thread was opened as a discussion rather than a question, so there was no option to mark it as answered. I’ve just moved it over and marked Kevin’s answer as such.
Allan