Reputation: 10720
I am working on a form where a uses chooses a date range in order to display information by using DataTables.
When the user clicks on the button, the dates are sent through jQuery .post() function and it retrieves the info as expected.
Here is the piece of the code related to it:
//Sending the dates range
$.post(url_route, datos, function(data,status){
if(status=='success'){
var response = jQuery.parseJSON(data);
//checking if data were found
if(response.list_events.length === 0){
console.log('No data available');
}
else{
//Let us display the info with DataTables inside div #list_events and
//table #table_id
$('#list_events').html('<table class="table table-striped table-hover" id="table_id"></table>');
$('#list_events table').append('<thead><tr><th>Event</th><th>Type</th><th>Attendance</th><th>Coordinators</th><th>Participants</th><th>Institutes</th><th>Talks</th></tr></thead><tbody></tbody>');
//retrieving the info for each row and append it to the table:
$.each(response.list_events,function(i,item)
{
$('#list_events').find('tbody').append('<tr>');
$('#list_events').find('tbody').append('<td>'+item.Event+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Type+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Attendance+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Coordinator+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Participant+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Institute+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Talk+'</td>');
});//end of each
//initializing DataTables
var table = $('#table_id').DataTable();
}//end of else (info found)
}//end of if success
}//end of post()
So far, the info is displayed in the DataTables but it is not totally working, since only the information is displayed. The DataTables search, next, and previous buttons, as well as the number of results dropdown menu are not shown.
In the console.log I get the following error:
Uncaught TypeError: Cannot read property 'length' of undefined
Any ideas? Can anyone shed some light on this?
Solved
The problem was with the append function.
If I type just one append with only the <tr>
like this:
$('#list_events').find('tbody').append('<tr>');
The result in HTML is <tr></tr>
That is to say, the tag is closed automatically ... no matter what. So, the solution was to put all the appends in one line like the following:
$('#list_events').find('tbody').append('<tr><td>'+item.Event+'</td><td>'+item.Type+'</td><td>'+item.Attendance+'</td><td>'+item.Coordinator+'</td><td>'+item.Participant+'</td><td>'+item.Institute+'</td><td>'+item.Talk+'</td></tr>');
And that was it ☺
Upvotes: 3
Views: 109
Reputation: 10830
If you are using a remote source for your data, it is far more elegant and efficient to let DataTables itself render the data for you.
In your example, you fetch the data, build the table, and then turn it into a "DataTable". If it meets the requirements and gets the job done, you've written perfectly fine code and you should read this answer no more!
But DataTables itself is awfully smart about rendering data detached from the DOM and then slotting it all in place. You get the benefit of more efficient updates while simultaneously having cleaner code.
Here's a basic example. Without testing it in your environment, I can't say for sure it will do your job, but I think it should:
var myTable = $('#table_id').DataTable( {
"ajax": {
"url": url_route,
"data": function(customData) {
customData.datos = datos // need some way to have access to datos
}
}
});
And then on click, if you want to retrieve newer data based on whatever has changed (the date range?) you just have to redraw.
myTable.draw();
I can imagine a few ways to get datos in there-- wrap it up in a function that accepts and uses datos. Declare a namespaced or otherwise quasi-global (or actually global if you're that guy!) variable that myTable would have access to at any given point in time... or even just destroy the current table and call the whole DataTable()
on it again.
Upvotes: 0
Reputation: 583
My first thought is that perhaps "response.list_events" is undefined. Certainly your error:
"Uncaught TypeError: Cannot read property 'length' of undefined"
seems to imply that.
My second thought is that I have recently done something similar where I had trouble with the .post method, and found success with the .ajax method.
Try something along these lines:
$.ajax({
type: "POST",
url: url_route,
data: datos,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(returned_from_server){
// your function here
}
});
My third thought is that I don't see where you put your closing row tags.
$.each(response.list_events,function(i,item)
{
$('#list_events').find('tbody').append('<tr>');
$('#list_events').find('tbody').append('<td>'+item.Event+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Type+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Attendance+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Coordinator+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Participant+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Institute+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Talk+'</td>');
$('#list_events').find('tbody').append('</tr>'); // <--- I believe you might be missing this!!
});//end of each
Hopefully this was some help.
Upvotes: 2