I've been attempting to track this one down for a few weeks but without any joy. So far as I can tell my markup is valid, which is not the case for most posts about this on SO.
<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>StudentId</th>
<th>Group</th>
<th>Student</th>
<th>4</th>
<th>1</th>
<th>7</th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>testgroup1</td>
<td>Test Name2</td>
<td><input type="text" id="row-4-1a" name="row-4-1a" value="0"></td>
<td><input type="text" id="row-4-1b" name="row-4-1b" value="0"></td>
<td><input type="text" id="row-4-2" name="row-4-2" value="0"></td>
</tr>
</tbody>
</table>
</div>
<button id="mytestbutton" type="submit">Submit form</button>
</div>
I have a C# backend that generates a lot of my content using Razor, but I've replicated the same behaviour using the source output from my browser. The JavaScript I'm using is as below, where I set some data into js objects from the backend ready to use, then initialise the DataTable on document ready.
var modelJson = JSON.parse('{"AssessmentId":1,"Name":"test1","Groups":[{"GroupId":1,"Name":"testgroup1","Students":[{"StudentId":4,"Name":"Test Name2","IsActive":true}],"StudentIds":[4],"IsActive":true}],"GroupIds":[1],"Questions":[{"QuestionId":0,"QuestionNumber":"1a","TopicDescription":"Topic goes here","AvailableMarks":4,"AssessmentId":0},{"QuestionId":0,"QuestionNumber":"1b","TopicDescription":"Topic goes here","AvailableMarks":1,"AssessmentId":0},{"QuestionId":0,"QuestionNumber":"2","TopicDescription":"Topic goes here","AvailableMarks":7,"AssessmentId":0}],"GradeBoundaries":{"A":80,"B":70,"C":0,"A*":90},"MarksAttained":[{"StudentId":4,"MarksAttained":{"1a":0,"1b":0,"2":0}}],"StudentIdsInAssessment":[4]}');
var columns = JSON.parse('[{"QuestionId":0,"QuestionNumber":"1a","TopicDescription":"Topic goes here","AvailableMarks":4,"AssessmentId":0},{"QuestionId":0,"QuestionNumber":"1b","TopicDescription":"Topic goes here","AvailableMarks":1,"AssessmentId":0},{"QuestionId":0,"QuestionNumber":"2","TopicDescription":"Topic goes here","AvailableMarks":7,"AssessmentId":0}]');
function InitialiseDataTable(e, t) {
var a = [];
e.forEach(function(e) {
a.push({
data: e.QuestionNumber,
name: e.QuestionNumber,
autoWidth: !0
})
}), $("#example").DataTable({
processing: !0,
serverSide: !1,
filter: !1,
orderMulti: !1,
data: {
test: 100
},
columnDefs: [{
targets: [0],
visible: !1,
searchable: !1
}],
columns: a
})
}
$("#mytestbutton").click(function() {
var e = $("#example").$("input, select").serialize();
return alert("The following data would have been submitted to the server: \n\n" + e.substr(0, 120) + "..."), !1
});
$(document).ready(() => {
InitialiseDataTable(columns, 1);
});
This code is all running live on jsfiddle at https://jsfiddle.net/w4q57hdu/ if you want to see the error in action.
I have been unable to determine why it's erroring where it is, I can only assume that there's something broken in the way I'm initialising the DataTable, but I can't see the wood for the trees. I loop through my columns object from the backend and use the QuestionNumber property from each in an array for initialising the DataTable.
It may be helpful to add that I followed the example at https://datatables.net/examples/api/form.html for this code.
I can see a few potential issues:
1) The columns Option
The columns data that you build contains a data option which is documented here. This expects to find the data for that column in an array containing objects of the given name.
So, for example, one of the values you push into the array is "data": "1a".
This means DataTables expects the first column to get its data from the values named "1a" in the data source.
2) The data Option
The data option (see here) tells DataTables where to look for the table data. For example, it's used by the above columns.data option. This option is supposed to contain an array of arrays, or an array of objects. It also needs to be valid JSON. In your case, it is just this: data: { test: 100 }. This is not valid JSON.
This also does not support the columns.data names expected (e.g. "1a" as noted above).
3) The HTML Table
DataTables also lets you define your data directly in the HTML table - which you have done here. This conflicts with using the data option, too.
A Quick Test
Comment out the data:... and columns:... options in your DataTable definition. You will no longer get any errors. This is just a quick way to confirm the above notes.
If you are providing all your data directly into the HTML table before initializing your DataTable object, then that may be all you need (like the example you are following).
One Way Forward
If you want to pass both the data and column definitions dynamically to DataTables via JSON (which I assume you do) then you can to do the following:
a) Strip down the HTML table by removing all its inner tags (<thead>, <tbody>). You will avoid your current conflicts by having an empty HTML table definition.
b) Provide column headings in the a.push section by using title: e.QuestionNumber, (or whatever field you want to use for headings). See here.
c) Use a function to build the input fields you need for the relevant column values. You need to do this because you no longer have these in the <html> definition.
For step (c), you can see an example here of how to dynamically render different types of data in your cell using render: function(...).
That should give you some pointers.
It may not get you to your end goal - but you should be able to move past your current error, and ask a more specific/targeted question, as needed (assuming it has not already been asked and answered here, of course).
I just included some logging into my application. For testing purpose, I filled the database with some test values (basically the same row over and over again, about 27k rows..).
Now I wanted to print the data on a view, doing this:
<table id="chatLogs">
<thead>
<tr>
<th>ID</th>
<th>Message ID</th>
<th>User Agent</th>
<th>IP:Port</th>
</tr>
</thead>
<tbody>
<?php
foreach($chatlogs as $log){ ?>
<tr>
<td><?=$log['ID'];?></td>
<td><?=$log['messageID'];?></td>
<td><?=$log['userAgent'];?></td>
<td><?=$log['IP'];?></td>
</tr>
<?php }
?>
</tbody>
</table>
$log is a variable I'm getting using the Database-Interface called Medoo.
Additionally, I included jQuery DataTables for better and sortable tables.
<script>
$(document).ready( function () {
$('#chatLogs').DataTable({
dom: 'Bfrtip',
buttons: [
'copy', 'excel', 'pdf'
]
});
} );
</script>
Now, until everything is done and the page is fully loaded, it takes about 15 seconds (with the 27k test-rows).
I just tested the same query directly on the database, and it takes 0.02 seconds, so its definetely about the PHP, not about the SQL.
And it seems like echoing everything in the table takes some time, as well as "loading it into DataTables"...
Now the question is: Is it possible to have it loading faster or instantly, and load the data, when its needed? I mean like only load the data into JSON and not echoing everything first (which is the longest part)? Because in the table, there are only 10 rows first anyway, and everytime I click on the next page, it could render it. Ofcourse though, all data would still need to be available for search.
Any ideas?
You could improve the loading time by loading only a set of records at a time using limit $start $stop to improve performance using php and sql or you could use "iDisplayLength", property of DataTable to do so.
I have this table right here that is populated by query results from my database:
<div class="card-block">
<table id="catTbl" class="display" width="100%" cellspacing="0" data-toggle="modal" data-target="#cat-update">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<?php
include "../processes/getLists.php";
$process = new getLists();
$process->getCatForTbl();
//used PHP PDO for that
?>
</tbody>
</table>
<p id="message" style="margin-top: 15px"></p>
</div>
I can properly update and insert rows in the database using ajax so the page won't load every after process but the problem is if I don't reload my page after every insert/update the datatable won't update with the newly updated/inserted rows.
I tried $("#catTbl").ajax.reload(), $("#catTbl").clear().draw() but they won't work unless my table is somehow made up of json. Is there anything I can do for my table to reload every after ajax call? Add: I don't want the whole page to reload, just the datatable on submit event.
$('#updateCatForm').on("submit", function(event){
event.preventDefault();
$.ajax({
url:"../ajax/updateCat.php",
method:"POST",
data:$('#updateCatForm').serialize(),
success:function(data){
$('#updateCatForm')[0].reset();
$('#cat-update').modal('hide');
$('#message').html(data);
//I put the table reload solutions here and nothing seemed to work :<
}
})
});
Use this
$('#example').DataTable().ajax.reload();
Make sure the selector is same. Or you can simply store in a variable and use it like this
var table = $('#example').DataTable();
Then after ajax
table.ajax.reload();
---Edit----
table.ajax.reload({
"ajax": {
"url": '${ctx}/work/list_ajax.json',
"type": 'POST',
"data":{
data:$('form').serialize()
}
}
});
I'm not entirely sure about this, I didn't give it a try but it's something along this line to get the data and display on the table. I'm sorry I couldn't provide you with a working snippet. Remeber the returned data should be in a proper format or it won't work.
I am using dyna table with Ajax. Sorting, searching, pagination nothing is working. I only get a list in my table but on clicking the column header nothing happens.
Please help.This is my code.
My html file is
<table style="width:100%" id="my-final-table" class="tablesorter" >
<thead>
<tr bgcolor="#239B56">
<th><font style="color:#fff">Rollno</font></th>
<th><font style="color:#fff">Name</font></th>
<th><font style="color:#fff">Marks</font></th>
<th><font style="color:#fff">Percentage</font></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
My Ajax code is
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="/jquery.dynatable.js"></script>
<style src="/jquery.dynatable.css"></style>
<script type="text/javascript">
$(document).ready(function()
{
$('#my-final-table').dynatable({
dataset: {
ajax: true,
ajaxOnLoad: true,
ajaxUrl: '/result_analysis_subject_json.json',
records: []
}
});
});
</script>
And my JSON file is
{"records":[{"rollno":"1","name":"Aditya Kumar Sharma","marks":"12.00","percentage":40},{"rollno":"2","name":"Aksh Kathuria","marks":"19.00","percentage":63},{"rollno":"3","name":"Anant ","marks":"14.00","percentage":47},{"rollno":"4","name":"Arnav Arora","marks":"28.00","percentage":93},{"rollno":"5","name":"Ayush Sai Raina","marks":"26.00","percentage":87},{"rollno":"6","name":"Ayush Rawat","marks":"21.00","percentage":70},{"rollno":"7","name":"Bhagya Dua","marks":"11.00","percentage":37},{"rollno":"8","name":"Bhvesh Gautam","marks":"26.00","percentage":87},{"rollno":"9","name":"Chaitanya Dubey","marks":"18.00","percentage":60},{"rollno":"10","name":"Chanchal","marks":"5.00","percentage":17},{"rollno":"11","name":"Deeksha","marks":"28.00","percentage":93},{"rollno":"12","name":"Dimple Bhatia","marks":"26.00","percentage":87},{"rollno":"13","name":"Ekta Yadav","marks":"27.00","percentage":90},{"rollno":"14","name":"Eshan Sharma","marks":"24.00","percentage":80},{"rollno":"15","name":"Harman Arora","marks":"13.00","percentage":43},{"rollno":"16","name":"Himanya ","marks":"18.00","percentage":60},{"rollno":"17","name":"Hiya Bhatia","marks":"29.00","percentage":97},{"rollno":"18","name":"Ishmeet Kaur","marks":"13.00","percentage":43},{"rollno":"19","name":"Jivitesh Gwadi","marks":"20.00","percentage":67},{"rollno":"20","name":"Jiya Hussain","marks":"7.00","percentage":23},{"rollno":"21","name":"Krish Kohli","marks":"13.00","percentage":43},{"rollno":"22","name":"Krishna Sharma","marks":"22.00","percentage":73},{"rollno":"23","name":"Lisha Kapoor","marks":"27.00","percentage":90},{"rollno":"24","name":"Mannant Sehgal","marks":"20.00","percentage":67},{"rollno":"25","name":"Mayank Mehta","marks":"19.00","percentage":63},{"rollno":"26","name":"Mehak Singh","marks":"26.00","percentage":87},{"rollno":"27","name":"Nandini Bhargava","marks":"29.00","percentage":97},{"rollno":"28","name":"Parth Talwar","marks":"27.00","percentage":90},{"rollno":"29","name":"Pawni Yadav","marks":"27.00","percentage":90},{"rollno":"30","name":"Prachi Dahiya","marks":"21.00","percentage":70},{"rollno":"31","name":"Prachi Sharma","marks":"18.00","percentage":60},{"rollno":"32","name":"Rashi Bainsla","marks":"19.00","percentage":63},{"rollno":"33","name":"Ravinder Singh","marks":"5.00","percentage":17},{"rollno":"34","name":"Riya Sethi","marks":"14.00","percentage":47},{"rollno":"35","name":"Sahib Kharbanda","marks":"24.00","percentage":80},{"rollno":"36","name":"Sajal Kukreja","marks":"23.00","percentage":77},{"rollno":"37","name":"Shrishty Singh","marks":"26.00","percentage":87},{"rollno":"38","name":"Tanisha Kaur","marks":"26.00","percentage":87},{"rollno":"39","name":"Toshiv Mudgal","marks":"16.00","percentage":53},{"rollno":"40","name":"Yash Anand","marks":"23.00","percentage":77}],"queryRecordCount":40,"totalRecordCount":40}
From what i can read from the documentation , the sorting, searching, and paginating needs to be done on the server side
NOTE: When using AJAX to load data, operations such as sorting, searching, and paginating are performed on the server before building the returned JSON. This example has these features disabled since, we're just loading a static JSON file for the purposes of documentation.
When using Dynatable in "AJAX mode" (dataset.ajax = true), delegates all operations (pagination, sorting, and querying/filtering) to the server. For each operation, dynatalbe culls the parameters (sort, search, page) into an AJAX request and fetches the results from dataset.ajaxUrl (if this setting isn't set, it will send an AJAX request to the URL of the current page).
more info
in the ajax call
records: function myFunction(rec){}
perform your js library code in myFunction on rec