Reputation: 215
I keep getting "Uncaught TypeError: Cannot read property 'aoData' of null" when I reload a Datatable via Ajax. I basically have one main datatable (table_1) with a link on each row that contains a pop up modal housing another datatable. (I use PHP to populate specific classes and id's for both the modal and the table inside to make sure they all remain unique.) Here's the code to explain what I'm talking about:
<table id="table_1">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><a data-toggle="modal" href="#<?=$row3->ID?>">link to open modal</a>
<div class="modal fade" id="<?=$row3->ID?>" tabindex="-1" role="basic" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 class="modal-title">My modal that houses a new table inside</h4>
</div>
<div class="modal-body">
<table id="new_<?=$row3->ID?>">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td align="center"><a class="edithours_<?=$row3->ID?>" href="javascript:;">Edit</a></td>
<td align="center"><a class="deletehours_<?=$row3->ID?>" href="javascript:;">Delete</a></td>
</tr>
</tbody>
</table>
<div class="table-toolbar">
<div class="btn-group pull-right">
<button id="new_<?=$row3->ID?>" class="btn green"> <i class="icon-plus"></i> Add </button>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div></td>
</tr>
</tbody>
</table>
Rows for datatables located inside the modals are able to be added, deleted, edited via ajax. Everything works great until I run an ajax call that completely reloads the entire thing. The Ajax call is successful, and all data gets loaded correctly, but for some reason after the reload I get the error stated above in my console log when I try to either edit, delete or save a row of a datatable located inside a modal. Note that main table still works fine and all of the modals work correctly. I can even add rows...I just can't edit, delete or save them. Here is the function that is calling the "second tier" datatables included with the functions that allow me to make edits. It is called both on load and after the ajax reload. (Note the var id being passed to the function is the number I use to help me identify the correct table and elements within)
function loadTables(id) {
var TableEditable = 'TableEditable_' + id;
window[TableEditable] = function() {
return {
//main function to initiate the module
init: function() {
function restoreRow(oTable, nRow) {
var aData = oTable.fnGetData(nRow);
var jqTds = $('>td', nRow);
for (var i = 0, iLen = jqTds.length; i < iLen; i++) {
oTable.fnUpdate(aData[i], nRow, i, false);
}
//oTable.fnClearTable(this);
oTable.fnDraw();
}
function editRow(oTable, nRow) {
var aData = oTable.fnGetData(nRow);
var jqTds = $('>td', nRow);
if (aData[0] == '2') {
var sickHours = ' selected="selected"';
var vacHours = '';
} else if (aData[0] == '3') {
var sickHours = '';
var vacHours = ' selected="selected"';
} else {
var sickHours = '';
var vacHours = '';
}
if (aData[2] == '') {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd
}
if (mm < 10) {
mm = '0' + mm
}
today = mm + '/' + dd + '/' + yyyy;
} else {
today = aData[2];
}
jqTds[0].innerHTML = '<select class="form-control input-small select2me"><option' + sickHours + ' value="2">Sick</option><option' + vacHours + ' value="3">Vacation</option></select></select>';
jqTds[1].innerHTML = '<input type="text" id="hours" class="form-control input-xsmall" value="' + aData[1] + '">';
jqTds[2].innerHTML = '<input class="form-control form-control-inline input-small2 date-picker" size="4" type="text" value="' + today + '" />';
jqTds[3].innerHTML = '<center><a class="edithours_' + id + '" href="">Save</a></center>';
jqTds[4].innerHTML = '<center><a class="cancelhours_' + id + '" href="">Cancel</a></center>';
FormComponents.init();
}
function editRow2(oTable, nRow) {
var aData = oTable.fnGetData(nRow);
var jqTds = $('>td', nRow);
if (aData[0] == '2') {
var sickHours = ' selected="selected"';
var vacHours = '';
} else if (aData[0] == '3') {
var sickHours = '';
var vacHours = ' selected="selected"';
} else {
var sickHours = '';
var vacHours = '';
}
if (aData[2] == '') {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd
}
if (mm < 10) {
mm = '0' + mm
}
today = mm + '/' + dd + '/' + yyyy;
} else {
today = aData[2];
}
jqTds[0].innerHTML = '<select class="form-control input-small select2me"><option' + sickHours + ' value="2">Sick</option><option' + vacHours + ' value="3">Vacation</option></select></select>';
jqTds[1].innerHTML = '<input type="text" id="hours" class="form-control input-xsmall" value="' + aData[1] + '">';
jqTds[2].innerHTML = '<input class="form-control form-control-inline input-small2 date-picker" size="4" type="text" value="' + today + '" />';
jqTds[3].innerHTML = '<center><a class="edithours_' + id + '" href="">Save</a></center>';
jqTds[4].innerHTML = '<center><a data-mode="new" class="cancelhours_' + id + '" href="">Cancel</a></center>';
FormComponents.init();
}
function saveRow(oTable, nRow) {
var jqInputs = $('input', nRow);
var jqSelect = $('select', nRow);
if (jqInputs[0].value == '' || jqInputs[1].value == '') {
alert('Please enter the required information.');
goSave = '0';
} else {
newNum4 = (Math.floor(jqInputs[0].value.replace(",", "") * 100) / 100).formatMoney(2, '.', ',');
if (jqSelect[0].value == '2') {
typeHour = 'Sick';
} else if (jqSelect[0].value == '3') {
typeHour = 'Vacation';
} else {}
goSave = '1';
oTable.fnUpdate(typeHour, nRow, 0, false);
$('td', nRow)[0].setAttribute('id', 'type_' + jqSelect[0].value);
oTable.fnUpdate(newNum4, nRow, 1, false);
oTable.fnUpdate('<center>' + jqInputs[1].value + '</center>', nRow, 2, false);
oTable.fnUpdate('<center><a class="edithours_' + id + '" href="">Edit</a></center>', nRow, 3, false);
oTable.fnUpdate('<center><a class="deletehours_' + id + '" href="">Delete</a></center>', nRow, 4, false);
oTable.fnDraw();
}
}
function cancelEditRow(oTable, nRow) {
var jqInputs = $('input', nRow);
var jqSelect = $('select', nRow);
newNum4 = (Math.floor(jqInputs[0].value.replace(",", "") * 100) / 100).formatMoney(2, '.', ',');
if (jqSelect[0].value == '2') {
typeHour = 'Sick';
} else if (jqSelect[0].value == '3') {
typeHour = 'Vacation';
} else {}
goSave = '1';
oTable.fnUpdate(typeHour, nRow, 0, false);
$('td', nRow)[0].setAttribute('id', 'type_' + jqSelect[0].value);
oTable.fnUpdate(newNum4, nRow, 1, false);
oTable.fnUpdate('<center>' + jqInputs[1].value + '</center>', nRow, 2, false);
oTable.fnUpdate('<center><a class="edithours_' + id + '" href="">Edit</a></center>', nRow, 3, false);
oTable.fnUpdate('<center><a class="deletehours_' + id + '" href="">Delete</a></center>', nRow, 4, false);
oTable.fnDraw();
}
var oTable = $('#tech_hour_dist_' + id).dataTable({
"bServerSide": false,
"bDestroy": true,
"iDisplayLength": 10,
// "sDom": "<'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-6'i><'col-md-6'p>>",
"sDom": "",
"sPaginationType": "bootstrap",
"oLanguage": {
"sEmptyTable": "No sick/vacation hours detected for this date range. Press the 'Add' button below to get started.",
"sLengthMenu": "_MENU_ records per page",
"oPaginate": {
"sPrevious": "Prev",
"sNext": "Next"
}
},
"aoColumnDefs": [{
'bSortable': false,
'aTargets': [0]
}],
"bSort": false
});
jQuery('#tech_hour_dist_' + id + '_wrapper .dataTables_filter input').addClass("form-control input-medium"); // modify table search input
jQuery('#tech_hour_dist_' + id + '_wrapper .dataTables_length select').addClass("form-control input-small"); // modify table per page dropdown
jQuery('#tech_hour_dist_' + id + '_wrapper .dataTables_length select').select2({
showSearchInput: false //hide search box with special css class
}); // initialize select2 dropdown
var nEditing = null;
$('#tech_hour_dist_new_' + id).click(function(e) {
// $('#tech_hour_dist_new_'+id).live('click', function (e) {
e.preventDefault();
var aiNew = oTable.fnAddData(['', '', '', '<center><a class="edithours_' + id + '" href="">Edit</a></center>', '<center><a class="cancelhours_' + id + '" data-mode="new" href="">Cancel</a></center>']);
var nRow = oTable.fnGetNodes(aiNew[0]);
editRow2(oTable, nRow);
nEditing = nRow;
});
$(document).on('click', 'a.deletehours_' + id, function(e) {
e.preventDefault();
var $row = $(this).closest('tr');
var job_id = $row.attr('id');
var thejobID = 0;
if (confirm("Are you sure to delete this?") == false) {
return;
}
var nRow = $(this).parents('tr')[0];
oTable.fnDeleteRow(nRow);
$.ajax({
url: URL + 'index.php/process/delete_tech_hours',
type: 'POST',
data: {
job_id: job_id
},
dataType: "html",
success: function(data) {}
});
});
$(document).on('click', 'a.cancelhours_' + id, function(e) {
e.preventDefault();
if ($(this).attr("data-mode") == "new") {
var nRow = $(this).parents('tr')[0];
oTable.fnDeleteRow(nRow);
} else {
restoreRow(oTable, nEditing);
nEditing = null;
}
});
$(document).on('click', 'a.edithours_' + id, function(e) {
e.preventDefault();
var $row = $(this).closest('tr');
var attr = $row.attr('id');
if (typeof attr !== 'undefined' && attr !== false) {
URLend = 'index.php/process/update_tech_hours';
job_id = $row.attr('id');
process = 0;
} else {
URLend = 'index.php/process/add_tech_hours';
job_id = '';
process = 1;
} /* Get the row as a parent of the link that was clicked on */
var nRow = $(this).parents('tr')[0];
if (nEditing !== null && nEditing != nRow) { /* Currently editing - but not this row - restore the old before continuing to edit mode */
restoreRow(oTable, nEditing);
editRow(oTable, nRow);
nEditing = nRow;
} else if (nEditing == nRow && this.innerHTML == "Save") { /* Editing this row and want to save it */
saveRow(oTable, nEditing);
nEditing = null;
if (goSave == '1') {
var tech = id;
var THEtype = $row.find('td:eq(0)').attr('id');
var type = THEtype.split("_");
var hours = $row.find('td:eq(1)').text();
var credit_date = $row.find('td:eq(2)').text();
var thejobID = 0;
$.ajax({
url: URL + URLend,
type: 'POST',
data: {
tech: tech,
type: type[1],
hours: hours,
credit_date: credit_date,
thejobID: thejobID,
job_id: job_id
},
dataType: "html",
success: function(data) {
if (process == 1) {
$row.attr("id", data);
}
FormComponents.init();
}
});
} else {
return;
}
} else { /* No edit in progress - let's start one */
editRow(oTable, nRow);
nEditing = nRow;
}
});
}
};
}();
window[TableEditable].init();
}
For some reason, I can get the delete function to work if I change it to just click() instead of on('click'....but the others just reload the page. I've been at this for days and I am about at my wits end. I realize it's lengthy, but if anyone has any good ideas or input I would be much appreciated. Also, I may have left something out so let me know if you need to see other code. Thanks!
Upvotes: 3
Views: 4878
Reputation: 1684
Please take a visit to: http://datatables.net/forums/discussion/12324/typeerror-osettings-is-null-in-var-osettings-fnsettingsfromnode-this-datatable-ext-iapiindex
The guy names IronMan has fixed it
Upvotes: 1