AJAX Paging in ASP.NET MVC using JQuery

In this article, we will look into paging using AJAX. We can use this approach to load few rows on page load and remaining on demand. Here, we will look into html table paging. I am going to explain it with a sample MVC application. Create an ASP.NET MVC 2 web application and name it as JQueryPaging. We no need to add JQuery script files manually, since MVC have built-in support for JQuery. We are not going to use any JQuery plug-ins in this sample. In this sample, we will create an html table and load rows into it on demand like clicking on next, previous links.

I added few images to content folder to show first, next page links. Now, create a SQL Server Database with a table called "Employees" under app_data folder. Create a LINQ to SQL class component [EmpDC.dbml] and drop Employees table onto it from Server Explorer. Add the below code to index view under Home controller:

<span id="sortMsg" style="text-align:center;color:Red;"></span>
<input type="hidden" id="pageIndx" value="0"/>
<input type="hidden" id="pageCount" value='<%= ((Math.Ceiling(
new JQuerySortAndPaging.EmpDCDataContext().Employees.Count()
/Convert.ToDouble(ConfigurationManager.AppSettings["pagSize"]))))-1 %>'/>
 <div id="loader"  style="color:Red;width:20;text-align:center;vertical-align:middle;"></div>
    <table border="1" id="empTable" style="width:50%;cursor:default">
        <thead>
            <tr>
                <th>
                    <u>Employee Name</u>
                </th>
                <th>
                    <u>Employee ID</u>
                </th>
                <th>
                    <u>Salary</u>
                </th>            
            </tr>
        </thead>
        <tbody>
            <%foreach (var emp in new
JQuerySortAndPaging.EmpDCDataContext().Employees.OrderBy
(x=>x.EmpId).Skip(System.Convert.ToInt32(0) * Convert.ToInt32
(ConfigurationManager.AppSettings["pagSize"])).Take(Convert.ToInt32
(ConfigurationManager.AppSettings["pagSize"])))
              {
                  %>
            <tr>
                <td>
                    <%=emp.EmpName %>
                </td>
                <td>
                    <%=emp.EmpId %>
                </td>
                <td>
                    <%=emp.Salary %>
                </td>
            </tr>
            <%} %>
        </tbody>
    </table>
    <br />
    <div id="pager" class="pager">
        <br />
        <img src="../../Content/first.ico" id="first" class="nav"/>
        <img src="../../Content/prev.ico" id="prev" class="nav" />
        <img src="../../Content/next.ico" id="next" class="nav" />
        <img src="../../Content/last.ico" id="last" class="nav" />
    </div>

sortMsg is used to show a status message during AJAX request. Hidden variable pageIndx is used to maintain current page index and pageCount to maintain number of pages based on total records by page size specified in config file. On page load, we will loop through employees table (sorted by Emp ID) and display first page records. When user clicks on next page link, we will load that data from server without page refresh by making an AJAX call using below script in site.master:

<script type="text/javascript">
       $(function() {
           $("#empTable tbody tr:visible:even").addClass("even");
           var hdnVal = $('#pageIndx');
           $('.nav').click(function() {
               if ($(this).attr('id') == 'next') {
                   if (parseInt($('#pageIndx').val()) < 0)
                       hdnVal.val(0);
               if (parseInt($('#pageCount').val()) == parseInt($('#pageIndx').val()))
                   return;
                   hdnVal.val(parseInt(hdnVal.val()) + 1); 
if (parseInt(hdnVal.val()) > parseInt($('#pageCount').val())) { hdnVal.val($('#pageCount').val()); }
               }
               if ($(this).attr('id') == 'prev') {
                   hdnVal.val(parseInt(hdnVal.val()) - 1);
               }
               if ($(this).attr('id') == 'first') {
                   if (parseInt($('#pageIndx').val()) < 0)
                       return;
                   hdnVal.val(0);
               }
               if ($(this).attr('id') == 'last') {
                   if (parseInt($('#pageCount').val()) == parseInt($('#pageIndx').val()))
                       return;
                   hdnVal.val(parseInt($('#pageCount').val()));
               }
               if ((!($(this).attr('id') == 'prev' && parseInt($('#pageIndx').val()) < 0)) && parseInt($('#pageIndx').val()) >= 0 && parseInt($('#pageIndx').val()) <= parseInt($('#pageCount').val())) {
                   $('#loader').html('Loading....').css('background-color', 'yellow').css('width', '50');
                   $.ajax({ type: 'POST', url: 'home/getdata', data: { pageIndx: $('#pageIndx').val() }, success: function(data) { $('#empTable tbody').html(data); $('#loader').html('').css('background-color', 'white'); $("#empTable tbody tr:visible:even").addClass("even"); }
                   });
               }
               if (parseInt(hdnVal.val()) < 0) { hdnVal.val(0); }
           });
       });
</script>

In above script, we are using JQuery's ajax() to call GetData() method of HomeController by passing pageIndx as shown below:

[HttpPost]
public string GetData(string pageIndx)
{
    var html = "";
  foreach (var emp in new JQuerySortAndPaging.EmpDCDataContext().Employees.OrderBy(x=>x.EmpId).Skip
    (System.Convert.ToInt32(Convert.ToInt32(pageIndx)) *          Convert.ToInt32(ConfigurationManager.AppSettings["pagSize"])).Take(Convert.ToInt32
    (ConfigurationManager.AppSettings["pagSize"])))
    {
         html += "<tr><td>" + emp.EmpName + "</td><td>" + emp.EmpId + "</td><td>" + emp.Salary + "</td> </tr>";
     }
     return html;
}

We are loading the rows by skipping the records of count  =  page size * current page index. Finally, I added some validations in the script. The output will be as shown below: 

1.gif

We can use this approach for showing huge data in page-wise without pulling complete data into browser. I am ending the things here. I am attaching the source code with it. I hope this article will be helpful for all.