Row().Node() null for pages that have not been browsed to
Row().Node() null for pages that have not been browsed to
Long story short, I am using a DataTable to present a set of data that the user can modify and then save back.
This mostly works with the exception of the following....when paging is enabled if the user does not browse to the secondary pages the node for the rows comes back as null. I'm guessing this is by design and they are only initialized when they are first displayed? Is there any work around for this outside of disabling paging?
The only other option I can think of is check for null nodes and then go back to the main data set and pull in the initial data to back fill.
// Data Table Creation
var dataTable = $('#industry-watchlist-table').DataTable({
ajax: {
type: 'GET',
url: getUrl("getWatchlistUrl"),
dataSrc: ""
},
autowidth: false,
//paging: false,
lengthMenu: [50, 100, 200, 500],
columns: [
{
data: 'company',
orderDataType: 'dom-text', type: 'string',
render: function (data, type, row, meta) {
return createTextInput("company", meta.row, data, "Company", 100);
}
},
{
data: 'newAddition',
orderDataType: 'dom-checkbox',
render: function (data, type, row, meta) {
return createCheckboxInput("newAddition", meta.row, data);
}
},
{
data: 'matchField',
orderDataType: 'dom-select',
render: function (data, type, row, meta) {
return createMatchFieldSelect("field", meta.row, data);
}
},
{
data: 'matchCondition',
orderDataType: 'dom-select',
render: function (data, type, row, meta) {
return createMatchConditionSelect("match", meta.row, data);
}
},
{
data: 'matchValue',
orderDataType: 'dom-text', type: 'string',
render: function (data, type, row, meta) {
console.log("rendering select menu");
return createTextInput("value", meta.row, data, "Value", 100);
}
},
{
data: 'selectSubsidiaries',
orderDataType: 'dom-checkbox',
render: function (data, type, row, meta) {
return createCheckboxInput("selectSubsidiaries", meta.row, data);
}
},
{
data: 'isSubsidiary',
orderDataType: 'dom-checkbox',
render: function (data, type, row, meta) {
return createCheckboxInput("isSubsidiary", meta.row, data);
}
},
{
data: 'notes',
orderDataType: 'dom-text', type: 'string',
render: function (data, type, row, meta) {
return createTextInput("notes", meta.row, data, "Notes", null);
}
},
{
data: null,
defaultContent: "",
render: function (data, type, row, meta) {
return createRemoveButton(meta.row);
}
}
],
columnDefs: [
{ targets: 0, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 1, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 2, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 3, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 4, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 5, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 6, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 7, className: 'dt-center', type: 'string', render: searchInputsAndSelects },
{ targets: 8, className: 'dt-center', type: 'string', render: searchInputsAndSelects }
],
select: {
style: 'os',
selector: 'td:first-child'
},
drawCallback: function () {
console.log("in drawcallback");
enableValidationForAllInputs();
}
});
//When the save button is clicked
$('#save-me').on('click', function () {
//Go through every row in the table and gather the data into an array
var _data = [];
dataTable.rows().every(function (rowIdx, tableLoop, rowLoop) {
var row = $(this.node());
var company = row.find("input[name*='company']");
var newAddition = row.find("input[name*='newAddition']");
var field = row.find("select[name^='field']");
var match = row.find("select[name^='match']");
var value = row.find("input[name*='value']");
var selectSubsidiaries = row.find("input[name*='selectSubsidiaries']");
var isSubsidiary = row.find("input[name*='isSubsidiary']");
var notes = row.find("input[name*='notes']");
_data.push({
"company": company.val(),
"newAddition": newAddition.is(':checked') ? 1 : 0,
"matchField": field.find(":selected").val(),
"matchCondition": match.find(":selected").val(),
"matchValue": value.val(),
"selectSubsidiaries": selectSubsidiaries.is(':checked') ? 1 : 0,
"isSubsidiary": isSubsidiary.is(':checked') ? 1 : 0,
"notes": notes.val()
});
});
//Post the array to the end point
$.ajax({
type: 'POST',
url: getUrl("updateWatchlistUrl"),
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(_data),
success: function (response) {
dataTable.draw();
savedModal.show();
},
error: (function () {
alert("Save failed.")
})
});
});
This question has an accepted answers - jump to answer
Answers
Add the option
deferRenderand set it tofalsefor Datatables to render all the rows at initialization.Kevin
Thanks that was it! I kept overlooking that setting because it seemed like render was getting called on everything. But I guess not!
columns.renderis called for various operations like type detection, sorting and filter operations.. It is called for every row for these operations. See the orthogonal docs for more details. Maybe that is what you are seeing.Kevin