Skip to main content

Jquery Datatable server side Paging/ Search/ Sort

If we have huge data to bind to Jquery Datatble, server side data binding is a handy option. As we can fetch a set of records and bind only those at time. Further next set of records can be retrieved when requested. e.g, if we have a page size set to 10 records in Datatable, it is a good choice to load only first 10 records in the datatable, when user click on "2" in pagination, we can retrieve 11-20 i.e, next 10 records from database and display in datatable. This will increase noticeable performance for datatable.

So let's dive in how we can achieve this,

<script src="~/Scripts/js/core/libraries/jquery.min.js"></script>
 <script type="text/javascript" src="~/Scripts/js/plugins/tables/datatables/datatables.min.js"></script>
 <script src="~/Scripts/js/plugins/tables/datatables/extensions/key_table.min.js"></script>
<!-- here I am using KeyTable (A datatable extension) to navigate through datatable using keyboard
 $(document).ready(function () {
            var table = $('#PurchaseorderList').DataTable({
                "processing": true, // for show progress bar
                "serverSide": true, // for process server side
               
                "filter": true, // this is for disable filter (search box)
                "orderMulti": true, // for disable multiple column at once
                "bPaginate": true,
                "ajax": {
                    "url": "@Url.Content("/Transactional/GetPurchaseOrder")",
                    "type": "POST",
                    "datatype": "json",
                    dataFilter: function (data) {
                        //debugger;
                        var json = jQuery.parseJSON(data);
                        json.recordsTotal = json.recordsTotal;
                        json.recordsFiltered = json.recordsFiltered;
                        json.data = json.data;
                        return JSON.stringify(json); // return JSON string
                    }
                },            
                "oLanguage": {
                    "sSearch": "Find: "
                },
                "columns": [
                       
                    { data: 'VoucherType', name: 'VoucherType', "autoWidth": true },
                    { data: 'VoucherNumber', name: 'VoucherNumber', "autoWidth": true },
                    { data: 'VoucherSeries', name: 'VoucherSeries', "autoWidth": true },
                    {
                        data: 'VoucherDate', name: 'VoucherDate', "autoWidth": true,
                        'render': function (jsondate) {
                            var date = new Date(parseInt(jsondate.substr(6)));
                            var month = date.getMonth() + 1;
                            return date.getDate() + "/" + month + "/" + date.getFullYear();
                        }
                    },
                    { data: 'Amount', name: 'Amount', "autoWidth": true },
                     { data: 'masterid', name: 'masterid', "autoWidth": true, "visible": false }
                   
                ],
                keys: true,
                keys: {
                    focus: ':eq(1)'
                },
            });
            table
                .on('key', function (e, datatable, key, cell, originalEvent) {
                    //alert('<div>Key press: ' + key + ' for cell <i>' + cell.data() + '</i></div>');
                    //debugger;
                    if (key == 13)  //This will be called when user press enter key, and we can read the values in the row
                    {
                        //debugger;
                        var table = $('#PurchaseorderList').DataTable();
                        var rows = table.rows('.selected').indexes();
                        var data = table.rows(rows).data();
                        var masid = data[0].masterid;
                        $('#hidentab').val(masid);                    
           
                       
                    }
                })
                .on('key-focus', function (e, datatable, cell) {
                    debugger;
                     var row = datatable.row(cell.index().row);
                    $(row.node()).addClass("selected");
                })
                .on('key-blur', function (e, datatable, cell) {
                    var row = datatable.row(cell.index().row);
                    $(row.node()).removeClass("selected");
                })
            .on('draw', function () {
                $('tr td:nth-child(2)').each(function () {
                 
                })
            });
       
                 
        });

Now let's have a look on controller side, I am using Asp.Net MVC, but you can use any server side language of your choice


  [HttpPost]
        public ActionResult GetPurchaseOrderList()
        {

            var draw = Request.Form.GetValues("draw").FirstOrDefault();
            var start = Request.Form.GetValues("start").FirstOrDefault();
            var length = Request.Form.GetValues("length").FirstOrDefault();
            var search = Request["search[value]"];
            //Find Order Column
            var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
            var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();

            int pageSize = length != null ? Convert.ToInt32(length) : 0;
            int skip = start != null ? Convert.ToInt32(start) : 0;
            int recordsTotal = 0;

//This is where we are fetching data from database
            var data = (from purordlist in ObjDB.masterpurchaseorders
                        join MasterAcc in ObjDB.masteraccounts on purordlist.AccountID equals MasterAcc.AccountID
                        where purordlist.VoucherType == FixAccounts.VoucherTypeForPurchaseOrder
                        select new
                        {
                            VoucherSeries = purordlist.VoucherSeries,
                            VoucherType = purordlist.VoucherType,
                            VoucherNumber = purordlist.VoucherNumber,
                            VoucherDate = purordlist.VoucherDate,
                            Amount = purordlist.Amount,
                            masterid = purordlist.ID
                        });


            if (!string.IsNullOrWhiteSpace(search))
            {
                data = data.Where(x => x.VoucherNumber.ToString().ToLower().Contains(search.ToLower()));
            }
            if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
            {
                data = data.OrderBy(q => sortColumn + " " + sortColumnDir);
             }
            recordsTotal = data.Count();
            var v = data.Skip(skip).Take(pageSize).ToList();
            return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = v }, JsonRequestBehavior.AllowGet);
            //return Json(data);
        }

That's it. Now your datatable is ready. You can load millions of records in datatable without performance issue.

The following image shows how fast we retrieve data with server side pagination/ search/ sort

Comments

Post a Comment

Popular posts from this blog

Keyboard driven menu in Jquery

I had a requirement to operate menu with keyboard just like we do in windows application. Traverse through menus using left/ right arrow keys, up/ down arrow keys should work as well. Further user should be able to navigate when Enter key is pressed. I was not able to find any jquery plugin to use for this purpose until I got this one,  https://hanshillen.github.io/jqtest/#goto_menubar This is what exactly I was looking, thanks a ton to the author. But later I realized it is not that easy to get just menu out of this. So I need to play with it and finally got it working. I am sharing code here so that if anyone ever need such type of menu it will be a quick one. This functionality is created by original author @Hans Hillen , I am just providing this code for simplicity. Download @  http://jmp.sh/Z3AtfVv

Jquery Datatable with Keytable setting focus

Datatable will not have focus by default, we need to set the focus on datatable by using below code, <script src="~/Scripts/js/core/libraries/jquery.min.js"></script> <script type="text/javascript" src="~/Scripts/js/plugins/tables/datatables/datatables.min.js"></script> <script src="~/Scripts/js/plugins/tables/datatables/extensions/key_table.min.js"></script> //make sure you have included KeyTable plugin $(document).ready(function () { // initialise your datatable here, after that we are ready to set focus on datatable so that we can use arrow key for navigation like excel var table = $('#PurchaseorderList').DataTable(); table.cell(':eq(0)').focus(); table.cell(':eq(0)').click(); });