Bootstrap & MVC ASP.NET Paging

Step by Step Tutorial to Make Paging using Bootstrap & MVC ASP.NET

Added by Nasir Mahmood updated on Thursday, October 24, 2013

Problem:

Contents of your site getting larger and you want to implement paging using Bootstrap & MVC ASP.Net.

Introduction:

Paging is very effective solution when contents of web sites are getting larger with respect to time. It is useful to handle data efficiently as well as low impact of network traffic. In other words you can say that you are providing latest and to the point information to your viewer, otherwise your viewer will be frustrated and feel hesitation to visit your site.

In this tutorial we will combine the power of MVC ASP.Net and Bootstrap UI paging to achieve our desire goal. Let’s start journey!

Prerequisites:

ASP.Net MVC Framework (Version 3 for this tutorial)
Twitter Bootstrap (Version 2.3.2 for this tutorial)

Step 1:

Start Visual studio and create a new project of "ASP.NET MVC 3 Web Application" and name it mvc_bootstrap_paging and press ok, as shown below

Next select "Internet Application" and press ok as show below

Step 2:

Lets our site is a collection of posts and site updated time to time, we want to display latest post first. So first of all create a PostModel class as below

public class PostModel
{
    public string Title { get; set; }
    public DateTime PostDate { get; set; }
    public string Author { get; set; }
    public string Detail { get; set; }
}

Now create a new class PostViewModel which act as viewmodel for our view as below

public class PostViewModel
{
    public List<PostModel> PostList { get; set; }
}

Step 3:

Now we have basic idea what to display, so we are going to make UI for our posts. So Add a new controller PostsController as shown below

Aftrer adding controller now we add view for it as shown below

After that add reference of bootstrap.css,bootstrap-responsive.css and jquery.js,bootstrap.js files to our _Layout file. Also add a menu entery for Posts. After running when we click on Posts it looks as shown below, currently we have nothing to display

Step 4:

Now create a folder with name Repository and create a class with name PostsRepository and add a Method GetPosts, currently we are using inmemory data we can also fetch data from database.

public List<PostModel> GetPosts()
{
    List<PostModel> list = new List<PostModel>();
    PostModel model = new PostModel()
    {
        Title = "Post Title 1",
        Author = "Author Name",
        PostDate = new DateTime(2013, 10, 1),
        Detail = "This is test data This is test data"
    };
    list.Add(model);
    model = new PostModel()
    {
        Title = "Post Title 2",
        Author = "Author Name",
        PostDate = new DateTime(2013, 10, 2),
        Detail = "This is test data This is test data"
    };
    list.Add(model);
    model = new PostModel()
    {
        Title = "Post Title 3",
        Author = "Author Name",
        PostDate = new DateTime(2013, 10, 3),
        Detail = "This is test data This is test data"
    };
    list.Add(model);
    /* ..... More Data .......*/
    return list.OrderByDescending(x => x.PostDate).ToList();
}

Now its time to display our posts to screen so we are going to add some code to our controller. Our Index action of PostsController looks as

PostsRepository objrepository = new PostsRepository();
public ActionResult Index()
{
    PostViewModel model = new PostViewModel()
    {
        PostList = objrepository.GetPosts()
    };
    return View(model);
}

Now go to PostView and add code as shown below


@model PostViewModel
<div>
@foreach (var post in Model.PostList)
{
    <div class="thumbnail">
        <h3>@post.Title</h3>
        <p>
            Added by <a href="#"><i class="icon-user"></i> @post.Author</a> on 
            <a href="#"><i class="icon-time"></i> @post.PostDate.ToString("D")</a>
        </p>
        <p>
            @Html.Raw(@post.Detail)
        </p>
    </div>
    <br />
}
</div>

Lets see the result

Here is a point where frustration of viewers start due to memory consumption of browser and very long contents, Mostly viewer doesn’t want to view irrelevant information. At the same time web server has to do extra work to fulfill such requests. As a result site goes slow done and at last server will be in not responding state. There is lot of other reasons to avoid such implementation.

Step 5:

To solve above problem pagination comes in mind, at the same time we want some eye catching UI for viewer. Bootstrap provided us such eye catching UI for paging, which is given below.


<div class="pagination">
  <ul>
    <li><a href="#">Prev</a></li>
    <li><a href="#">1</a></li>
    <li><a href="#">2</a></li>
    <li><a href="#">3</a></li>
    <li><a href="#">Next</a></li>
  </ul>
</div>

Our task is to generate above code dynamically according to conditions.

Make a model PageInfoModel under Models folder as shown below

public class PageInfoModel
{
    public int CurrentPage { get; set; }
    public int PageSize { get; set; }
    public int TotalPages { get; set; }
}

Step 6:

Crate a new static class of BootstrapPageHelper and add a static Method PageItem which is used to create li tag and it represents our page item, its code shown below

public static string PageItem(string url, string caption, bool active = false, bool disabled = false)
{
    TagBuilder li = new TagBuilder("li");
    if (disabled)
    {
        li.MergeAttribute("class", "disabled");
        TagBuilder span = new TagBuilder("span");
        span.InnerHtml = caption;
        li.InnerHtml = span.ToString();
    }
    else
    {
        if (active)
        {
            li.MergeAttribute("class", "active");
        }
        TagBuilder a = new TagBuilder("a");
        a.MergeAttribute("href", url);
        a.InnerHtml = caption;
        li.InnerHtml = a.ToString();
    }
    return li.ToString();
}
}

Our next task is create an extension helper method which will generate html output based on requirements i.e set active our current page,disable first,previous pages when we are on first page and enable rest of pages similarly disable next,last pages when we are on last page, and also show number of page item left & right from current page.its code is shown below.

public static MvcHtmlString BootstrapPager(this HtmlHelper html, PageInfoModel pinfo, Func<int, string> pageUrl)
{
    StringBuilder navbar = new StringBuilder();
    navbar.Append("<ul>")
    navbar.Append(PageItem(pageUrl(1), "First", false, (pinfo.CurrentPage == 1) ? true : false));
    string prev = (pinfo.CurrentPage == 1)
        ? PageItem(pageUrl(pinfo.CurrentPage - 1), "Prev", false, true)
        : PageItem(pageUrl(pinfo.CurrentPage - 1), "Prev");
    navbar.Append(prev);
    var start = (pinfo.CurrentPage <= 3) ? 1 : (pinfo.CurrentPage - 2);            
    var end = (pinfo.CurrentPage > (pinfo.TotalPages - 2)) ? pinfo.TotalPages : pinfo.CurrentPage + 2;
    for (int i = start; i <= end; i++)
    {
        string pageHtml;
        pageHtml = (i == pinfo.CurrentPage)
            ? PageItem(pageUrl(i), i.ToString(), true)
            : PageItem(pageUrl(i), i.ToString());
        navbar.Append(pageHtml);
    }
    string next = (pinfo.CurrentPage == pinfo.TotalPages)
        ? PageItem(pageUrl(pinfo.CurrentPage + 1), "Next", false, true)
        : PageItem(pageUrl(pinfo.CurrentPage + 1), "Next");
    navbar.Append(next);
    navbar.Append(PageItem(pageUrl(pinfo.TotalPages), "Last", false,
                 (pinfo.CurrentPage == pinfo.TotalPages) ? true : false));
    navbar.Append("</ul>")
    return MvcHtmlString.Create(navbar.ToString());
}

Step 7:

Add property PageInfo of PageInfoModel to our PostViewModel class as shown below

public class PostViewModel
{
    public List<PostModel> PostList { get; set; }
    public PageInfoModel PageInfo { get; set; }
}

Now Modify our GetPosts Method of PostsRepository and also Index method of PostsController as show below

public List<PostModel> GetPosts(int page,int pagesize)
{
    ......
    ......
    ......
    
    return list.OrderByDescending(x => x.PostDate).Skip((page - 1) * pagesize).Take(pagesize).ToList();
}
       
public ActionResult Index(int? page=1)
{
    if (page == null)
        page = 1;
    int totalposts = 12;
    int pagesize = 2;
    int totalpages = (int)Math.Ceiling((decimal)totalposts / pagesize);    
    PostViewModel model = new PostViewModel()
    {
     PostList = objrepository.GetPosts((int)page,pagesize), PageInfo = new PageInfoModel()
        { CurrentPage =(int)page, PageSize = pagesize, TotalPages = totalpages }
            
    };    
    return View(model);
}

Now run the project and see the result, it will shows only two records on page, How to navigate to other posts? becase we can see only two posts at a time.

Step 8:

Add below code to our Index view of Posts controller and thats it, run project and see results


<div class="pagination pull-right" style="margin: 0px 0px 0px 0px">  
	    @Html.BootstrapPager(Model.PageInfo, x => Url.Action("Index", new { page = x }))  
</div>

Download Source Code

About

29 Tutorials
25 Snippets
6 Products

More

Contact Us

Contact us

Stay Connected