-2

The json output that I have is below

[{"param1":"value1","param2":"value2","param3":"value3"},{"param1":"value1","param2":"value2","param3":"value3"}]

My ajax request is coded in a function so that it can called based on button click:

function callAjaxRequest()
{
ajaxRequest = $.get('getdata',{ 'parameter1': paramValue1,'parameter2':paramValue2 },function(responseinjson) {

if(responseinjson!=null){
        $("#table1").find("tr:gt(0)").remove();
        var tablevar = $("#table1");
        $.each(responseinjson, function(key,value) {

             var rowNew = $("<tr><td><td></td></tr>");
                rowNew.children().eq(0).text(value['param1']); 
                rowNew.children().eq(1).text(value['param2']); 
                rowNew.appendTo(tablevar);
        });

        var numberofrecords = responseinjson.length;

        }

}
}

I initialized ajax request to variable because I can abort it later in some cases.

Now my problem is I can see lot of delay in the for each loop based on the huge number of records. So, can someone please suggest me how to implement pagination according to the responseinjson value using datatable in jquery. I have seen lot of examples on the internet but I can't get my head around it on how to use according to the response that I get. Please go easy on my question if it sounds noob as I am new to web development.

P.S: I don't want to add to datatable using for each loop because it results in same delay that I am getting now.

Reiterating my point for bounty: I am getting entire json response in the ajax call as per my code snippet. But I found that it is taking considerable delay to show up the data, so the for each jquery loop to show data is taking too much time. So, is there anyway that I can paginate this without lopping through the entire json response.

Apparatus
  • 411
  • 1
  • 5
  • 19
  • get the data in smaller chunks like 20 records per pagination click and place the data in the table. – Jai Nov 07 '14 at 07:34
  • @Jai can you please elaborate? I want to use datatable so that by default it provides pagination. – Apparatus Nov 07 '14 at 08:05
  • The delay you're seeing may be from the inefficient way you're building the table. A bit of string concatenation and a single appendTo() instead of one for every row would undoubtedly be much faster. – wwwmarty Nov 10 '14 at 15:43
  • @wwwmarty I think it's better to paginate, because it's taking same almost same time though I appended only once and used string concatenation. – Apparatus Nov 10 '14 at 16:37
  • @Apparatus: If you will load all the data at once and pass it to datatables then the performance will become worse depending on how larger the data set is .. but to counter this issue you can use the datatable server side option and load the data on request .. have a look into this : http://www.datatables.net/examples/server_side/simple.html – Qarib Haider Nov 17 '14 at 11:26
  • I don't know whether this will help you? But is this the problem with the ajax request response time.?[Only when the complete json response is recieved, the processing starts] Can you paginate it in the backend.? So that for each of the request you send, you get a small json document with smaller response time. So the page will load fastly in front end also. – Sony Mathew Nov 17 '14 at 15:44

7 Answers7

1

Datatables has an in-built pagination feature, but using a server-side data source means that you can handle the paging in the server code.

Datatable initialisation:

var oTable = $('#mytable').dataTable({
    'bServerSide': true,
    'iDisplayLength': 25,
    'iDeferLoading': 0,
    'sAjaxSource': 'your-url-that-returns-json',
    'bProcessing': true,
    'aoColumns': [
        {
            //...
        }
    ]
});

Note the use of iDeferLoading which prevents initial population on page load; use .fnDraw(); so as to load on a button click.

When you make the request, parameters relating to paging, searching, sorting, etc., the corresponding values are also passed in into the query string and made accessible for use when querying the data.

For example in C#:

public ActionResult PopulateMyTable(jQueryDataTableParamModel param)
{
    var mydata = query the database
    var results = mydata.Skip(param.iDisplayStart).Take(param.iDisplayLength);
    // ...
}

jQueryDataTableParamModel is just a class to contain all the datatable parameters.

iDisplayStart & iDisplayLength are parameters passed in the request to populate the datatable, and used to return the paged data.

Then, return the json data:

return Json(new {
    param.sEcho,
    iTotalRecords = rowCount,
    iTotalDisplayRecords = rowCount,
    aaData = results
    }, JsonRequestBehavior.AllowGet
);
Community
  • 1
  • 1
markpsmith
  • 4,860
  • 2
  • 33
  • 62
  • Hi just a comment, actually (matter of the context) you don't have to manage the paging on server side (at least being a performance issue) you can just return the whole rows and datatables plugin will do the rest in client side: `Server-side processing is useful when working with large data sets (typically >50'000 records)` maybe we're good still with client side in here https://datatables.net/reference/option/serverSide – Allende Nov 14 '14 at 16:41
  • @Allende - I agree that while you don't _have_ to manage paging on the server, not making use of the opportunity for a speed increase seems short-sighted IMHO. – markpsmith Nov 14 '14 at 17:09
  • That's why I mentioned, a matter of context meaning, server capacity,bandwith (intranet/internet), number of concurrent clients and their capacity, max # of rows, does the information change quickly (meaning we need fresh data then server side processing or we don't) and probably many other thing I'ven't think about it. I'm sorry not meaning to argue you'r answer but complement. – Allende Nov 14 '14 at 17:54
0

Refer to the following code, for Ajax and Datatable

$(document).ready(function() {
    $('#example').dataTable( {
        "processing": true,
        "serverSide": true,
        "ajax":{ 
               "url" : "../server_side/scripts/server_processing.php",
               "data":{
                       //your variable
                       }
               }
    } );
} );

Refer to the link here Datatable

Captain Planet
  • 408
  • 3
  • 19
  • I have already seen this. How can I assign the ajax request to a variable here, so that I can abort it whereever I need. Please go through my question again. – Apparatus Nov 07 '14 at 08:16
  • You are saying that if you send the request and you need to abort before getting the response. – Captain Planet Nov 07 '14 at 08:22
  • o_O Where can I find that you assigned ajax request in your code? Yes, I might abort ajax requests in some cases before getting the response. – Apparatus Nov 07 '14 at 08:23
  • You can send your variables in the data attribute to the url.And about the abort refer this [link](http://stackoverflow.com/questions/446594/abort-ajax-requests-using-jquery) – Captain Planet Nov 07 '14 at 08:33
  • I am already using this kind of abort functionality by assigning ajax request to variable. – Apparatus Nov 07 '14 at 08:36
0

You can do something like this (syntax depends on the plugin version too!):

1) Declare a function which manages your requests (check the syntax, I use custom utilities and this is not exactly what I have in my code), it's reausable: var fnServerData = function (sSource, aoData, fnCallback, oSettings) { var jqXHR = $.ajax({ dataType : 'json', url : sSource, data : aoData, success : fnCallback }); oSettings.jqXHR = jqXHR; return jqXHR; };

2) Reference it in your datatable declaration, example:

$('#example').dataTable({ "bPaginate": true, "bServerSide": true, "iDisplayLength": 10, "iDisplayStart": 0, "sAjaxSource": 'yoursource', "fnServerData": fnServerData });

RamonDR
  • 1
  • 1
  • I used this plugin (ref. http://www.datatables.net/plug-ins/api/fnReloadAjax, which internally calls the "fnServerData" I mentioned. Note: in the latest API this plugin is deprecated in favor of ajax.reload() (ref. http://www.datatables.net/plug-ins/api/fnReloadAjax). There are also default events: xhr and preXhr, see (ref. http://datatables.net/reference/event/) you can investigate; but I fear if you don't want to use my old hack, some new hack on the plugin is needed. – RamonDR Nov 07 '14 at 11:08
0

If you're having issues with the amount of time this is taking to build the DOM elements I'd suggest looking at the performance implications of the way you are building row and cell elements.

Have a look at this JSFiddle http://jsfiddle.net/e4oc2jbj/ . On my browser using the jQuery based code you've got takes 200 ms to add 1000 rows, where as using native DOM method takes around 7ms

var newRow = table.insertRow(0);
var newCell = newRow.insertCell(0);
newCell.appendChild(document.createTextNode(value['param1']));
newCell.appendChild(document.createTextNode(value['param2']));

Maybe with better performance you wont need to page the data?

Sam Greenhalgh
  • 5,952
  • 21
  • 37
  • Thanks for your answer. But I might get even 20k to 30k rows, at that time I am getting unresponsvie script, script might be busy......... So, can you please suggest me the way to paginate this instead? – Apparatus Nov 10 '14 at 16:56
0

You can include this pagination plugin to achieve pagination in datatables:

http://www.datatables.net/plug-ins/pagination/
ashfaq.p
  • 5,379
  • 21
  • 35
0

Besides create DOM elements as @Sam Greendhalgh mentioned, considere create a table "in-memory" instead of taking the one from the DOM and append rows to it.

I have tested your code and I can see the problem could be that you'r append elements directly to the DOM.

i.e.:

$("#myTable").find("tr:gt(0)").remove();
    var tablevar = $("#myTable");               
    for(var i=1;i<=100;i++){
        var rowNew = $("<tr><td><td></td></tr>");
        rowNew.children().eq(0).text("hola"); 
        rowNew.children().eq(1).text("hola"); 
        rowNew.appendTo(tablevar);
     }

The above code will create/render and append the rows directly to the DOM, that's very costly in performance for any browser and we're talking about 14k rows in your case.

So besides the recommendations about native methods to create the rows, you should consider (it might help, not sure) create the whole table in a previous element created in memory (see this answer: How to use createElement to create a new table? or search for others here in StackOverflow.)

then append the whole table to the DOM, and just render/show the rows according to your page size instead of showing the whole table.

Another thing it could help you current code, is set the table to hidden (it might help, again not sure): var tablevar = $("#myTable").hide();

Hope my answer help you a bit, but if it doesn't you can always to avoid invent the wheel: http://www.datatables.net/

And about:

is there anyway that I can paginate this without lopping through the entire json response.

Try with JSON.parse you coul try somethign like:

 var myjsobj = JSON.parse('[{"param1":"value111","param2":"value222","param3":"value333"},{"param1":"value1","param2":"value2","param3":"value3"}]');

 //now you could acess to your object using an index
 console.log(myJsObj[0]);  //so "just" left to implement the pagination logic

You would need to add an index for it in the json object so you can keep of the current position

Community
  • 1
  • 1
Allende
  • 1,480
  • 2
  • 22
  • 39
0

my approach would be to go through the loop and call everything inside your loop in

document.setTimeout(function(){}, 0)

this way everything is pushed into the Queue and wont be blocking your interactions on the UI because your Render Queue can still push its rendering inbetween your loops..

basicly it doesnt spam your stack and just works it off when there's time for it.

I Hope you consider my answer. It worked for me aswell in a simular task ;)

Max Bumaye
  • 1,017
  • 10
  • 17