Reputation: 2424
i'll start by saying i saw there is lots of information about this topic but i just couldn't find one solid answer to make it clear what will consider to be best practice when trying to update table after Ajax call.
I have an HTML table which i want to update with new data after user generates ajax call by selecting date range. After range is chosen Ajax call creates new table and i update the DOM like this:
$(document).ready(function(){
$('#selecDate').on('DOMSubtreeModified',function(){
range = getRange() ;
$.ajax({
type: 'POST',
url: '/revenue',
data: {'start' : range[0], 'end' : range[1]},
dataType: 'json',
success: function(response){
updateTable(response);
},
error: function(response){
console.log('error:' + response);
},
});
});
});
updateTable(response)
- the function that's being called when the response accepted:
function updateTable(response){
var table = '<table class="table table-bordered data-table sortable" id="rev-table"><thead>';
table += '<tr><th colspan="10">Income</th><th colspan="9">Spent</th>';
table += '<tr><th>Website Name</th><th>Google</th>...LOTS OF LINES
var total_spent= response[website]['total_spent'];...LOTS OF LINES
table += '<tr><td>' + website + '</td>';
table += '</tr>';
}
table += '</tbody></table>';
$('#rev-table-cont').html(table);
it's a long table so i chopped a big part but i guess you got the idea... wherever i wrote LOTS OF LINES, they all do pretty much the same thing The problem: I used to be able to sort the table with this code:
$(document).ready(function(){
$('#rev-table').DataTable({
"bJQueryUI": true,
"processing": true,
"sPaginationType": "full_numbers",
"sDom": '<""l>t<"F"fp>'
});
$('select').select2();
$('.active').removeClass("active");
$('#revenueReport').addClass("active");
});
But now after creating the new table and updating the DOM with this line
$('#rev-table-cont').html(table);
the table is not sortable anymore, the code takes no effect and i have no errors in the console. I found some leads about this all topic like this link: https://datatables.net/reference/api/ajax.reload(), or in many question here, but it just something that i cant get a clear answer about i should i solve this problem..does creating a new table like i am doing wil consider to be best practice or is there another way? why is the table not sortable anymore after ajax call? any lead will be very helpfull...thx!
Upvotes: 1
Views: 2885
Reputation: 61904
You haven't shown it, but I assume that when the page loads, there is a table with id "rev-table" which is a child of the "rev-table-cont" element. This table has the DataTable functionality applied to it (as per your script).
The problem is, after the ajax is applied, you create a new <table>
element to replace it, but you don't give it an id.
There are a couple of solutions:
1) Change <table class="table table-bordered data-table sortable">
in your updateTable
method so it gives the table the right id: <table class="table table-bordered data-table sortable" id="rev-table">
. Then since it's effectively a new element, you will probably need to re-apply the DataTable functionality to it (i.e. using the same $('#rev-table').DataTable(...
code as you already have.
This has a couple of disadvantages - you might end up duplicating some code you don't need to, and probably any existing sorting/filtering etc. settings that the user had set on the table will be destroyed, which might annoy them.
2) This is the option I would go for: Don't delete and recreate the table, only alter the rows within it. Change the function along these lines:
function updateTable(response)
{
var tableBody = $("#rev-table tbody");
tableBody.empty(); //delete all the existing rows (from the body only, not the header)
//here, process your response data to create new rows. You can create a new row like this:
var row = $("<tr/>");
//now go through your data items and append all the necessary cells. You can create a cell, and append it to the row something like this:
$("<td/>", { text: response[website]['total_spent'] }).appendTo(row);
//repeat that for each cell you need. Then once you have all the cells, append the row to the table:
row.appendTo(tableBody);
//and repeat that for each row you need
}
Upvotes: 2