couldn't load the data to the datatable using server side pagination - javascript

I have tried to implement the server side pagination concept for my table (jQuery(v1.12.4),datatable(v1.10.15))
As per the datatable server side pagination documentation
I have enabled serverSide, paging, processing as true and specified the sPaginationType along with the ajax.
In the Custom Data Source Property article, it is mentioned that we need to use dataSrc Option being used as a string to get the data from a different source property, in this case demo but it could be any value, included a nested property by using standard dotted Javascript object notation.
I have used the dataSrc as per the above point ie., "dataSrc": "data" based on my json response.
However the data is not being loaded.
My table loads only the approve button (which i have defined in the columns section) rest of the columns are empty. - convening that the data are not rendered in the table.
Refer Output 2 image.
Since I have used deferLoading first page returns empty data. Refer Output 1 image.
I have referred all the below mentioned articles
Custom data source property dataSrc and pagination issue
Datatables server side processing pagination issue
The code is snippet is shown below, please help
$('#vschildtable').DataTable({
"language": {
"processing": "Please
wait - LOADING SCAN Result...", "
emptyTable " : "
Currently no
data found in this project " }, "
bJQueryUI " : true, "
paging " :
true,
"sPaginationType": "full_numbers",
"processing ": true,
"serverSide": true,
"columns": [{
"defaultContent": "",
"visible": false
}, {
"defaultContent": "",
"visible": false
}, {
"defaultContent": ""
}, {
"defaultContent": ""
}, {
"defaultContent": ""
}, {
data: null,
defaultContent: ' <
button type = "button"
class = "btn-approve label label-link bg-green " > Approve < /button>
' } ], "deferLoading" : 57, "ajax" : { "url" : "emppage?empID=" +
encodeURIComponent(empID) + "&projectId=" +
encodeURIComponent(projectID) + "&subProjectId=" +
encodeURIComponent(subProjectID) + "&pageNo=" +
encodeURIComponent(offset),
type: 'POST',
datatype: "jsonp",
"dataSrc": "data"
}
});
Json response:
[{
"message":"SUCCESS",
"data":"{\"data\":\[{\"projectId\":1,\"subProjectId\":1,\"empID\":765,\"empName\":\"Arjun\",\"empIDVersion\":\"1%3A4.1.4\",\"fkempID\":7781,\"tmpempID\":354999,\"noOfDept\":1,\"rowNo\":1,\"totalnoOfDept\":1},{\"projectId\":1,\"subProjectId\":1,\"empID\":765,\"empName\":\"Arjun\",\"empIDVersion\":\"4.0.18.1\",\"fkempID\":7781,\"tmpempID\":355000,\"noOfDept\":1,\"rowNo\":2,\"totalnoOfDept\":1},{\"projectId\":1,\"subProjectId\":1,\"empID\":765,\"empName\":\"Arjun\",\"empIDVersion\":\"4.2.1\",\"fkempID\":7781,\"tmpempID\":355001,\"noOfDept\":1,\"rowNo\":3,\"totalnoOfDept\":1}\]}"
}]

As far as I can see, there's missing information in the data returned by the server. DataTables expects some specific data (draw,recordsFiltered,etc.) from the server when running in server side mode. You can check here
Furthermore, You should add the data property to each object in the columns array, specifying the name of the data you expect to render in that column, i.e.:
columns:[
{ data:'projectId' }
{ data:'subPorjectId'}
...
]
this tells DataTables what data to show in which column.
Hope it helps!

Related

Jquery Datatable Server Side Pagination With External Search field

I have a Jquery Datatable which displays some data and it has an external search field.I am trying to implement Server side pagination with the help of Jquery Datatable plugin.But the problem is,it has an external search field,in which user can select a date(basically month and year) and search for the records.So, every time user opt for a search the datatable need to be refreshed.Can anyone help me on this.
Datatable
var LeaveDetailsTable = $('#LvReprtTable').DataTable({
"pageLength": 5,
"processing": true,
"serverSide": true,"searching": false,"bLengthChange": false,
"ajax": {
"url": "GetLeaveDetails",
"type": "POST",
"datatype": "json",
"data": function (d) {
d.EmpId = empId;
d.UserType = userType;
d.Month = "1";
d.year = "2017";
}
},
"columns": [
{ "data": "_fromdate" },
{ "data": "_todate" },
{ "data": "_strLvType" },
{ "data": "_leavedurationtype" },
{ "data": "_leavedurationtype" },
{ "data": "_leavedurationtype" },
],
"columnDefs": [{
"targets": -1,
"data": data,
"defaultContent": "<button>Click!</button>"
}]
,"language":
{
"processing": "<div class='row text-center waitIconDiv' id='LoadIconDiv'><img alt='Progress' src='~/Content/images/wait_icon.gif' width='50' height='50' id='imgProgLvRprt' /></div>"
},
});
Month and year may vary.
You would need to call the ajax.reload() on the datatable instance in whatever event of whatever element you want :
LeaveDetailsTable.ajax.reload();
which will post the state of datatables with your new parameters that got added in data property to the controller action.
You can also take a look at this article (Server Side Advanced Search using JQuery DataTables) which explains how to send custom parameters to controller action with JQuery DataTables.
To achieve this I recommend you to use jquery onchange method. For example:
$('.input-class').on('change', function () {
$table.fnDraw();
});
Here $table refers the name of your Datatable and fnDraw() is a Datatable function to refresh your table.
And obviously you need to add data from search field to the request. For this, I recommend you going through link below:
datatables

JavaScript: Datatables serverside processing - change values before display

For displaying my data in a table, I use the dataTable plugin. As I have a big amount of data, I use the serverside processing. My problem is, that I have some data fields in my obtained JSON, that I would like to change before i display it in the table.
Example: I get values, whether some equipment is available or not. This is written as "", 0 or 1 in datasbase, for displaying it I would like to convert these values to "Yes" or "No" or "N/A".
To initialise the table I use the following code:
table = $('#table').DataTable({
"ajax": "myurl",
"sPaginationType": "full_numbers",
"sAjaxDataProp":"",
"deferRender": true,
columns: [
{data: 'attributes.0.value'},
{data:'attributes.1.value'},
{data:'attributes.2.value'},
{data:'attributes.3.value'},
{data:'attributes.4.value'}],
});
To bind the conerting function directly in the data array doesn't work (like
{data: convert(attributes.0.value)},
There are some parameters for the datatable plugin, which I tried, but I'm not sure, if they can solve my problems. This is an example from the documentation of the plugin:
$('#example').dataTable( {
"ajax": {
"url": "data.json",
"data": function ( d ) {
d.extra_search = $('#extra').val();
}
}
});
Can I use the data parameter to solve my problems (when I tried this, d is always empty) or it there another possibility to change my values before I integrate them in a table?
You could preprocess the JSON in an ajax.dataSrc function, but since you really just need to modify how the values are shown I would go for column rendering :
columns: [
{ data: 'attributes.0.value',
render: function(data, type, row) {
switch(data) {
case '0' : return 'No'; break;
case '1' : return 'Yes'; break;
default : return 'N/A'; break;
}
},
{ data: 'attributes.1.value' },
{ data: 'attributes.2.value' },
{ data: 'attributes.3.value' },
{ data: 'attributes.4.value' }
]
Use the above render method to each of the column values you need to convert.

How to better define JQuery DataTables column rendering?

We use JQuery DataTables extensively. I am now switching all the app tables to AJAX data source to better support search and to render tables faster.
The problem I am having is how to define data rendering inside my table columns. I do not render only data in the column but I need to have some additional markup in some columns (like <span class="label">data</span> or links, etc.).
This can be done via javascript, here is how I did it. The problem is I don't want to have this column definition syntax for every table in my app. Not two tables are identical, and to support all tables/columns like this it would result in bunch of javascript code for every table. I don't see this as a good practice.
$('.data-table').each(function(){
initialize_ajax_data_tables($(this));
});
function initialize_ajax_data_tables(element)
{
var display_rows = element.attr('data-rows') ? parseInt(element.data('rows')) : 25;
var initial_sort = element.attr('data-sort') ? element.data('sort') : [0, 'asc'];
dataTables = element.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
url: base_url+'ajaxprocess/products_data_table.json',
type: 'GET'
},
"columns": [
{ "data": "id" },
{ "data": "product_type_name" },
{ "data": "code" },
{ "data": "name" },
],
"columnDefs": [
{
"render": function ( data, type, row ) {
return '<span class=\"label label-info\">'+ data +'</span>';
},
"targets": 1
},
{
"render": function ( data, type, row ) {
return '<span class=\"label label-success\">'+ data +'</span>';
},
"targets": 2
},
],
"pageLength": display_rows,
"order": initial_sort,
});
dataTables = $.fn.dataTable.fnTables(true);
}
Is there a way to somehow define this column definition/rendering in HTML itself and then pull this in the javascript when initialising DataTables? Or any other way on how to approach this issue?
For sorting rules and pageLength on the DataTables I use data-attributes from the <table> element and that works perfect. This way I define attributes like:
<table id="DataTables_Table_0" class="data-table" data-rows="50" data-sort="[0,"desc"]">
This works fine, but can not use this for columnDefs arrays as render attribute expects function.
I am making some progress and am posting my findings bellow. Maybe some find this useful, but I would still be open to other solutions in case you have a better design.
Currently I have split my code into two three sections:
Main application JS file: common DataTables initialisation code for all the application tables
View: HTML table view generated by the backend and served to the browser. In this view I define table specific properties which are then referenced in in common DataTable init code
Backend AJAX script which serves table data
So to demonstrate this with actual code.
1. Main initialisation code
$('.data-table').each(function(){
initialize_data_tables($(this));
});
function initialize_data_tables(element)
{
if(!(element instanceof jQuery)) element = $(element);
var table_defs = element.attr('data-table-def') ? eval(element.data('table-def')) : [];
dataTables = element.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
url: table_defs.url,
type: 'POST'
},
"columns": table_defs.columns,
"pageLength": table_defs.rows,
"order": table_defs.sort,
});
dataTables = $.fn.dataTable.fnTables(true);
}
2. The HTML view
Here I define specific JS object for table definition, column definition and so on. Every table in app has specific definition. This structure also allows me to have multiple data tables on the view at the same time and reference the right JS object with table properties definition.
<script type="text/javascript">
var tableDef = {
url: "<?= Uri::create('utilities/ajaxprocess/products_data_table.json') ?>",
columns: [
{ "data": "id" },
{ "data": "product_type_name", render: function ( data, type, row ) {
return '<span class=\"label label-info\">'+ data +'</span>';
}
},
{ "data": "code" },
{ "data": "name" },
],
rows: 50,
sort: [ 0, 'desc' ]
};
</script>
<table class="data-table" data-table-def="tableDef”>...</table>
3. The backend
No need to paste my code here. Just functions that query my database and prepare data to be served via AJAX to DataTables.
Following your idea I would say try to define the render methods somewhere and bind them through data attributes.
This solution would be rather easy to test, but I don't think you can work around the columnDefs problematic.

Datatables Dynamic AJAX POST

Using Datatables with AJAX / POST, I initialize like this, where experiment_list is a list, and $("#type") is a selector menu.
var my_table = $('#my_table').DataTable( {
"ajax": {"url": "/experiment_data/", "type":"POST", "data": {"experiments": experiment_list, "type": $("#type_selector").val() } },
"dom": '<"top">rt<"bottom"fp><"clear">',
} );
The problem I am having is that "type" is at initialization to the selector menu value, and changing the value after that and reloading the data, does not change the value in the "ajax" method.
$("#type_selector").change(function () {
console.log($("#type_selector").val());
position_table.ajax.reload()
});
The API Documentation only has .url() for a dynamic method, which would mean either using GET (which is not very good for object type data) or rewriting views for each selector 'type' (and changing the url on select).
Is there a way to update the Data load of the Post request Dynamically?
Did you try with the sample request they provide ?
$('#example').dataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"url": "/experiment_data/",
"data": function ( d ) {
d.experiments = experiment_list;
d.type = $("#type_selector").val();
}
}
});
If it fails, can you provide the log of Firebug please ?

jQuery datatable clears radio button in header

I have a jQuery Datatable with 3 headers. One header contains two radio buttons, another header contains a select box. By default, one of the options is checked.
When I use the search function in the Datatable to search for specific records, it does not display which radio button was checked. I inspected the DOM after I used the datatable search, and the input element still contains the CHECKED attribute. The select box is not affected. It still retains the value of the select box.
Also, IE behaves fine. O_o FF and Chrome are not recognizing the checked value.
I tried a $(selector).datatable().fnDraw();... no dice.
How do I get the datatable to recognize the checked attribute after, or during, the search? Has anyone experienced something similar?
Any help is appreciated. Thanks.
Edit: After further investigation, it looks like the fnDraw is clearing the value of the radio button.
Code
Initialize datatable (Javascript)
$.get('store_handler.ashx', { cmd: '9', pubId: pubId, sub: sub }, function(o) {
$("#researchTableDiv").html(o.datatableContent);
$('#ResearchTable').dataTable({
"bJQueryUI": true,
"bPaginate": false,
"sScrollY": "450px",
"bSort": false
});
if (o.radioCheck == "single")
$('#radioSingle').attr("checked", "checked");
else
$('#radioSub').attr("checked", "checked");
}, "json");
HTML of datatable headers (C# .Net)
htmlString.Append("<thead>");
htmlString.Append("<tr>");
htmlString.Append("<th valign=\"middle\" style=\"width: 200px; text-align: left;valign:top;border-right:0px;padding-bottom:0px\" class=\"header\">Filter: ");
htmlString.Append("<select name=\"nonSort2\" style=\"height:20px;padding:0px;margin-top:-0px;font-size:11px\">");
htmlString.Append("<option value=\"AKLPH\">All</option>");
htmlString.Append("<option value=\"-\">---------------</option>");
htmlString.Append("<option value=\"AK\">Alaska</option>");
htmlString.Append("<option value=\"AL\">Etc...</option>");
htmlString.Append("</select>");
htmlString.Append("</th>");
htmlString.Append("<th align=\"left\" class=\"header\" >");
if (sub == "0")
{
htmlString.Append("<input type=\"radio\" value=\"0\" name=\"rdoSubscription\" id=\"radioSingle\" checked=\"CHECKED\" style=\"margin-left:1px\"/>Single Report");
htmlString.Append("<input type=\"radio\" value=\"1\" name=\"rdoSubscription\" id=\"radioSub\" onclick=\"getPubDetails('" + pubId + "','1');\" style=\"margin-left:1px\"/>Subscription");
jOut.Put("radioCheck", "single");
}
else
{
htmlString.Append("<input type=\"radio\" value=\"0\" name=\"rdoSubscription\" id=\"radioSingle\" onclick=\"getPubDetails('" + pubId + "','0');\" style=\"margin-left:1px\"/>Single Report");
htmlString.Append("<input type=\"radio\" value=\"1\" name=\"rdoSubscription\" id=\"radioSub\" checked=\"CHECKED\" style=\"margin-left:1px\"/>Subscription");
jOut.Put("radioCheck", "sub");
}
htmlString.Append("</th>");
htmlString.Append("<th class=\"header\" align=\"center\">Action</th>");
htmlString.Append("</tr>");
htmlString.Append("</thead>");
Try setting the radio button after the draw event:
$.get('store_handler.ashx', { cmd: '9', pubId: pubId, sub: sub }, function(o) {
$("#researchTableDiv").html(o.datatableContent);
$('#ResearchTable').dataTable({
"bJQueryUI": true,
"bPaginate": false,
"sScrollY": "450px",
"bSort": false,
"fnDrawCallback": function() {
if (o.radioCheck == "single")
$('#radioSingle').attr("checked", "checked");
else
$('#radioSub').attr("checked", "checked");
}
}
});
}, "json");
I just had a similar problem, and solved it by reading the issue in red on this link. Maybe it can help you, maybe not, but hopefully it can.
I build a lot of DataTables in my applications, but it seems like in a way you're attempting to "brute force" a server side solution. Technically, what you're doing is a dom-based table because you're outputting HTML and having DataTables format it, though it appears from the $.get that you could be trying to leverage a server-side solution. Server side is actually far more efficient because the server is limiting what it sends to the jQuery and lessening the need to deal with hundreds (or in my case millions) of records at once. Obviously, it's also faster to take a raw json stream and build a table rather than having to traverse dom structure to get the same information.
I'd suggest trying a true server side solution.....for the sole reason that the data comes straight from your server-side technology of choice and doesn't get heavily manipulated as it obviously is here. So, first, setup your a file (perhaps your store_handler.ashx) to output what you need in JSON (the most efficient transfer method for this operation) The string should look something like this:
{"sEcho": 1, "iTotalRecords": 1, "iTotalDisplayRecords": 1, "aaData":[["one", "for", "each", "column"]]}
Make sure when doing this that you get your JSON outputting to screen first, and test it to ensure validity via jsonlint.com
Then, the jQuery would look something like this:
$('#detailstable').dataTable( {
"aaSorting": [[ 1, "asc" ]],
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "handler.ashx",
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"bAutoWidth": false,
"bLengthChange": true,
"bPaginate": true,
"bSort": true,
"iDisplayLength": 10,
"bInfo": true,
"aoColumns": [
{ "sTitle": "One", "sWidth": "15%" , "sClass":"center"},
{ "sTitle": "For", "sWidth": "15%" , "sClass":"center"},
{ "sTitle": "Each", "sWidth": "15%", "sClass":"center" },
{ "sTitle": "Column", "sWidth": "15%" , "sClass":"center"}
],
"fnServerData": function ( sSource, aoData, fnCallback ) {
var something = $('#something').val();
var somethingelse = $('#somethingelse').val();
aoData.push( { "name": "something", "value": something },
{ "name": "somethingelse", "value": somethingelse }
);
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": fnCallback
} );
}
});
-- edit --
I added the fnServerData section which is a callback that sends data to the query. In the example given, it will make the variables something and somethingelse available in a $_REQUEST string to be used in the query. You could use this to get the values of the selected fields back to the query to give you results.
-- edit --
Now, for the searching, you would have to add some elements to your source page to handle sorting/filtering/searching/etc. This is a lot simpler than it sounds...each variable is passed via a $_REQUEST variable. Check the tutorial online for an example of what comes in and how to sort on it. Yes, the tutorial is in PHP, but the important part is figuring what values it's passing you and from that you can build your query accordingly. Ignore the PHP specific elements of the tut. We can help you out if it's still confusing.
Voila...more efficient, less confusing, and doing nearly exactly what you're talking about works in my applications without a problem. No javascript voodoo required.

Categories

Resources