Efficient Paging and Sorting with WebGrid Web Helper – ASP.NET MVC

Today we will discuss about ASP.NET MVc webgrid with efficient pagging and sorting my previous article covers only paging in addition to that sorting on same.

Features
Web grid will fetch only number of record per page irrespective to sorting.
Paging at the bottom of page
Sorting and paging will work simultaneously

Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sample.Models;
using System.Web.Helpers;
using System.Linq.Expressions;

namespace Sample.Controllers
{
    public class EfficientController : Controller
    {
        private readonly List<Product> _mostPopular;
        public EfficientController()
        {
            _mostPopular = new List<Product>()
            {
                new Product() {ID = 1, Name = "Jack", Price = 30},
                new Product() {ID = 2, Name = "Riley", Price = 40},
                new Product() {ID = 3, Name = "William", Price = 17},
                new Product() {ID = 4, Name = "Oliver", Price = 56},
                new Product() {ID = 5, Name = "Lachlan", Price = 25},
                new Product() {ID = 6, Name = "Thomas", Price = 75},
                new Product() {ID = 7, Name = "Joshua", Price = 93},
                new Product() {ID = 8, Name = "James", Price = 15},
                new Product() {ID = 9, Name = "Liam", Price = 73},
                new Product() {ID = 10, Name = "Max", Price = 63},
                new Product() {ID = 11, Name = "Thomas", Price = 75},
                new Product() {ID = 12, Name = "Joshua", Price = 93},
                new Product() {ID = 13, Name = "James", Price = 15},
                new Product() {ID = 14, Name = "Liam", Price = 73},
                new Product() {ID = 15, Name = "Max", Price = 63}
            };
        }
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public JsonResult EfficientPaging(int? page, string sort = "", string sortdir = "")
        {
            int skip = page.HasValue ? page.Value - 1 : 0;
            var sortedProduct = SortIQueryable<Product>(_mostPopular.AsQueryable(), sort, sortdir);
            
            sortedProduct = sortedProduct.Skip(skip * 5).Take(5);
            var grid = new WebGrid(sortedProduct);
            var htmlString = grid.GetHtml(tableStyle: "webGrid",
                                          headerStyle: "header",
                                          footerStyle : "foot",
                                          alternatingRowStyle: "alt",
                                          htmlAttributes: new { id = "DataTable" });

            var tempData = htmlString.ToHtmlString();
            return Json(new
            {
                Data = htmlString.ToHtmlString(),
                Count = _mostPopular.Count() / 5, 
                CurrentPage = skip, 
                Sort = sort,
                Sortdir = sortdir
            }, JsonRequestBehavior.AllowGet);
        }

        public IQueryable<T> SortIQueryable<T>(IQueryable<T> data, string fieldName, string sortOrder)
        {
            if (string.IsNullOrWhiteSpace(fieldName)) return data;
            if (string.IsNullOrWhiteSpace(sortOrder)) return data;

            var param = Expression.Parameter(typeof(T), "i");
            Expression conversion = Expression.Convert(Expression.Property(param, fieldName), typeof(object));
            var mySortExpression = Expression.Lambda<Func<T, object>>(conversion, param);

            return (sortOrder == "desc") ? data.OrderByDescending(mySortExpression)
                : data.OrderBy(mySortExpression);
        }
    }
}

Now on view page

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Product</h2>

<script type="text/javascript" >
    $(document).ready(function () {
        $.getJSON("/Efficient/EfficientPaging", null, function (d) {
            // add the dynamic WebGrid to the body
            $("#divMain").html(d.Data);

            // create the footer
            var footer = createFooter(d.Count, d.CurrentPage);
            $("#hdnSort").val(d.Sort);
            $("#hdnSortDir").val(d.Sortdir);

            $(".header a").live("click", function (e) {
                var Parameters = e.target.search;
                var sort = getParameterByName("sort", Parameters);
                var sortdir = getParameterByName("sortdir", Parameters);
                $("#hdnSort").val(sort);
                $("#hdnSortDir").val(sortdir);
                getPageData(e, d, "First");
                return false;
            });
            $(".foot a").live("click", function (e) {
                getPageData(e, d, $(this).text());
            });
        });
    });


    function getPageData(e, d, currentPage) {
        //$("#divFoot a").click(function (e) {
        e.preventDefault();
        // Manage Pagging 
        var PageCount = 1;
        if (currentPage == "First") {
            PageCount = 1;
        }
        else if (currentPage == "Last") {
            PageCount = d.Count;
        }
        else if (currentPage == "Next") {
            if (d.Count == $("#hdnCurrentPage").val())
                PageCount = d.Count;
            else
                PageCount = (parseInt($("#hdnCurrentPage").val()) + 1);
        }
        else if (currentPage == "Previous") {
            if ($("#hdnCurrentPage").val() == 1)
                PageCount = 1;
            else
                PageCount = (parseInt($("#hdnCurrentPage").val()) - 1);
        }
        else
            PageCount = parseInt(currentPage);

        var data = {
            page: PageCount, 
            sort: $("#hdnSort").val(), 
            sortdir: $("#hdnSortDir").val()
        };

        // get data of current page 
        $.getJSON("/Efficient/EfficientPaging", data, function (html) {
            // add the data to the table    
            $("#DataTable").remove();
            $("#divMain").html(html.Data);
            var footer = createFooter(d.Count, html.CurrentPage);
        });
    }

    function getParameterByName(name, href) {
        name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
        var regexS = "[\\?&]" + name + "=([^&#]*)";
        var regex = new RegExp(regexS);
        var results = regex.exec(href);
        if (results == null)
            return "";
        else
            return decodeURIComponent(results[1].replace(/\+/g, " "));
    }


    function createFooter(d, CurrentPage) {
      
        var rowsPerPage = 5;
        var footer = "<div>";
        if ((CurrentPage + 1) == 1) {
            footer = footer + "First &nbsp;";
            footer = footer + "Previous&nbsp;";
        }
        else {
            footer = footer + "<a href=#>First</a>&nbsp;";
            footer = footer + "<a href=#>Previous</a>&nbsp;";
        }
        for (var i = 1; i < (d + 1); i++) {
            if ((CurrentPage + 1) == i) {
                footer = footer + "" + i + "&nbsp;";
                $("#hdnCurrentPage").val(i);
            }
            else
                footer = footer + "<a href=#>" + i + "</a>&nbsp;";
        }
        if ((CurrentPage + 1) == d) {
            footer = footer + "Next &nbsp;";
            footer = footer + "Last &nbsp;";
        }
        else {
            footer = footer + "<a href=#>Next</a>&nbsp;";
            footer = footer + "<a href=#>Last</a>&nbsp;";
        }

        footer = footer + "</div>";
        $("#divFoot").empty();
        $("#divFoot").append(footer);
       
        return footer;
    }   
</script>

<style>
    table
    {
        font-family: verdana,arial,sans-serif;
        font-size: 11px;
        color: #333333;
        border-width: 1px;
        border-color: #999999;
        border-collapse: collapse;
        width:27%;
    }
    table th
    {
        background: #b5cfd2;
        border-width: 1px;
        padding: 8px;
        border-style: solid;
        border-color: #999999;
    }
    table td
    {
        background: #dcddc0;
        border-width: 1px;
        padding: 8px;
        border-style: solid;
        border-color: #999999;
    }
    .foot
    {
        background: #dcddc0;
        border-width: 1px;
        padding: 8px;
        border-style: solid;
        border-color: #999999;
        text-align:center;
        width:25%;
    }
</style>

<input type="hidden" id="hdnCurrentPage" />
<input type="hidden" id="hdnSort" />
<input type="hidden" id="hdnSortDir" />
<div id="divGrid" >
    <div id="divMain" ></div>
    <div id="divFoot" class="foot" ></div>
</div>

Relevant links
Sorting in webgrid in ASP.NET MVC
Delete Multiple webgrid row using jQuery
Efficient Paging and Sorting with WebGrid Web Helper – ASP.NET MVC
ASP.NET MVC3 webgrid conditional statement on column (if, if else loop)
Efficient Paging with WebGrid Web Helper – ASP.NET MVC
ASP.NET MVC Web Grid Style

Advertisements
This entry was posted in ASP.NET MVC Web Grid, jQuery, MVC and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s