Announcement

Friday, 23 May 2014

Server side ajax paging using jquery MVC4

Server Side AJAX paging using jquery in MVC4


Every developer has to code for a view that displays all the records. But what if the database consists of thousands of records? In that case displaying all the records on the view is not good. Rather some sort of paging must be provided that will give the user the ability to navigate among the records and even provide the developer to have fast web page. So, we need to fetch the records on demand and display them on the view. This will be much fast if records are fetched using AJAX. Pagenation can be done in different ways. One way is to use Html Helpers. i.e., @Html.PagedList. The other way is using AJAX. So, how AJAX is used for fast paging?


While searching a lot on the internet, I came across a post of the Joe Stevens' that explained it in a nice way.

I have done this in a different manner though much of the logic is same.

So here we go.

First create a generic class called PagedData<T> that will contain three properties:


public IEnumerable<T> Data { get; set; }

public int NumberOfPages { get; set; }

public int CurrentPage { get; set; }


Data is generic list type i.e., IEnumerable<T> because we will retrieve our records in Data that will contain list of records.

NumberOfPages is of int type to get/set number of pages.

CurrentPage is of int type to get/set current page.

Here is the complete class:



public class PagedData<T> where T : class

{
/*This is IEnumerable because It will return a list of records.i.e, data. */
public IEnumerable<T> Data { get; set; }
public int NumberOfPages { get; set; }
public int CurrentPage { get; set; }
}


Now, we need to set information for our first page. i.e, records to be displayed on the first page.

You are thinking in the right direction. We need to write our Index Action Method where we will set our page size, i.e, number of records to be displayed on each page. We will also calculate number of pages by using old formula: DataCount/PageSize.

So here we go:


public const int PageSize = 5;

public ActionResult Index()

{
var user = new PagedData<User>();
using (var ctx = new AppEntities())
{
user.Data = ctx.Users.OrderBy(p =>p.UserName).Take(PageSize).ToList();
user.NumberOfPages = Convert.ToInt32(Math.Ceiling((double)ctx.Users.Count()/PageSize));
}
return View(user);
}


You will notice that initially we have set the page size to 5 and kept it as constant.
Now ready for the show. Its time to display the results.

You are on the edge. Right. Its time to code for view. We will create a partial view for the display. This partial view will rendered from the Index view.




@model App1.Uitlity.PagedData<App1.Entities.User>

<table>
<tr>
<th>
@Html.DisplayName("UserName")
</th>
<th>
@Html.DisplayName("FirstName")
</th>
<th>
@Html.DisplayName("LastName")
</th>
<th>
@Html.DisplayName("EmailId")
</th>
<th>
@Html.DisplayName("MobileNumber")
</th>
<th>
@Html.DisplayName("Address")
</th>
<th>
</th>
</tr>
@foreach (var user in Model.Data)
{
<tr>
<td>
@Html.DisplayFor(modelItem => user.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => user.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => user.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => user.EmailId)
</td>
<td>
@Html.DisplayFor(modelItem => user.MobileNumber)
</td>
<td>
@Html.DisplayFor(modelItem => user.Address)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = user.SystemUserId }) |
@Html.ActionLink("Details", "Details", new { id = user.SystemUserId }) |
@Html.ActionLink("Delete", "Delete", new { id = user.SystemUserId })
</td>
</tr>
}
<tfoot>
<tr>
<td colspan="3">
@for (int i = 1; i <= Model.NumberOfPages; i++)
{
<input type="button" class="page-number" value=@i />
}
</td>
</tr>
</tfoot>
</table>


Now, create an Action Method for the partial view that will update the partial view each time page button is clicked.




public ActionResult UsersList(int page)

{
var people = new PagedData<User>();
using (var ctx = new AppEntities())
{
people.Data = ctx.Users.OrderBy(p => p.UserName).Skip(PageSize * (page - 1)).Take(PageSize).ToList();
people.NumberOfPages = Convert.ToInt32(Math.Ceiling((double)ctx.Users.Count()/ PageSize));
people.CurrentPage = page;
}
return PartialView(people);
}
Now we are left with the Index wherein partial view will get rendered and of course the main thing, call to the UsersList Action Method. We will give it a call from the Index view using jquery ajax.




@model App1.Uitlity.PagedData<App1.Entities.User>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<div id="user-list">
@Html.Partial("~/Views/User/UsersList.cshtml")
</div>
<script type="text/javascript">
$('.page-number').live('click',function () {
var page = $(this).val();
$.ajax({
url: '@Url.Action("UsersList", "User")',
data: { page: $(this).val() },
success: function (result) {
$('#user-list').html(result);
},
Error: function () {
alert("Unsuccessful ajax call.");
}
});
});
</script>


REMEMBER: Don't forget to have your model updated with the table User. i.e., Include table User in the .edmx file.

We are using the Live function here so that when the page gets refreshed with ajax the click event handler is re-applied to the paging links(buttons). First we get the page number from the input tag and then make an ajax call to UsersList action method, the result of which is the rendered in the partial view with the page of data. We then replace the content of the “user-list” DIV with that HTML.

Congratulations! You are done with ajax server side paging.

2 comments:

Mohd. Amir Ansari said...

I have tried it with over 1,25,000 records in the table and its working lightening fast.

Mohd. Amir Ansari said...
This comment has been removed by the author.