AspBucket offers ASP.NET, C#, VB, Jquery, CSS, Ajax, SQL tutorials. It is the best place for programmers to learn

Thursday 14 April 2016

How to implement custom paging in MVC using partial view?

In this article I will discuss how to implement custom paging in MVC using partial view? Custom paging will increase the performance of a page. Since we don't need to render all records on a page. I am using here twitter bootstrap for design, Linq & Entity framework for paging. Let's start discussing how to implement it.
Step-1 Implement interface IPagedList.
public interface IPagedList
 {
        int TotalCount { get; }
        int PageCount { get; }
        int Page { get; }
        int PageSize { get; }
  }

Step 2- Create Generic class PagedList
public class PagedList<T> : List<T>, IPagedList
    {
        public int TotalCount { get; private set; }
        public int PageCount { get; private set; }
        public int Page { get; private set; }
        public int PageSize { get; private set; }

        public PagedList(IQueryable<T> source, int page, int pageSize)
        {
            TotalCount = source.Count();
            PageCount = GetPageCount(pageSize, TotalCount);
            Page = page < 1 ? 0 : page - 1;
            PageSize = pageSize;
            if (pageSize == 0 && Page == 0)
            {
                AddRange(source.ToList());
            }
            else
            {
                AddRange(source.Skip(Page * PageSize).Take(PageSize).ToList());
            }
        }

        private int GetPageCount(int pageSize, int totalCount)
        {
            if (pageSize == 0)
                return 0;

            var remainder = totalCount % pageSize;
            return (totalCount / pageSize) + (remainder == 0 ? 0 : 1);
        }
    }

Step 3- Create Static class PagedListExtensions
  public static class PagedListExtensions
    {
        public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int page, int pageSize)
        {
            return new PagedList<T>(source, page, pageSize);
        }
    }

Let's say I want to use custom paging for table EmailLog. EmailLog have following columns like FromUserId,ToUsers, CCUsers,Subject, Message,CreatedOn table structure is shown in below image

Step 4-Add new class FilterEmailLogs
 public class FilterEmailLogs
    {
        public int _EmailLogId = 0;
        public DateTime? _StartDate = null;
        public DateTime? _EndDate = null;
        private string _OrderBy = "EmailLogId";
        private string _OrderDir = "ASC";
        private int _PageNumber = 0;
        private int _PageSize = 0;

        public int EmailLogId
        {
            get
            {
                return _EmailLogId;
            }
            set
            {
                _EmailLogId = value;
            }
        }
        public DateTime? StartDate
        {
            get
            {
                return _StartDate;
            }
            set
            {
                _StartDate = value;
            }
        }
        public DateTime? EndDate
        {
            get
            {
                return _EndDate;
            }
            set
            {
                _EndDate = value;
            }
        }

        public string OrderBy
        {
            get
            {
                return _OrderBy;
            }
            set
            {
                _OrderBy = value;
            }
        }

        public string OrderDir
        {
            get
            {
                return _OrderDir;
            }
            set
            {
                _OrderDir = value;
            }
        }

        public int PageNumber
        {
            get
            {
                return _PageNumber;
            }
            set
            {
                _PageNumber = value;
            }
        }

        public int PageSize
        {
            get
            {
                return _PageSize;
            }
            set
            {
                _PageSize = value;
            }
        }
    }

Step 5- Add new method for paging & filter records from Email.
    #region--Get Email Logs
        public List<EmailLogsEntity> GetEmailLogs(FilterEmailLogs _filter)
        {
            List<EmailLogsEntity> rType = new List<EmailLogsEntity>();
            using (HRMEntities db = new HRMEntities())
            {
                var temp = (from e in db.EmailLogs
                            join u in db.Users
                            on e.FromUserId equals u.UserId
                            where ((e.EmailLogId == _filter.EmailLogId) || (_filter.EmailLogId == 0))
                            && ((_filter.StartDate == null) || (_filter.StartDate <= e.CreatedOn))
                            && ((_filter.EndDate == null) || (_filter.EndDate >= e.CreatedOn))
                            select new EmailLogsEntity
                            {
                                EmailLogId = e.EmailLogId,
                                FromUserId = e.FromUserId,
                                FromUserName = u.UserName,
                                ToUsers = e.ToUsers,
                                CCUsers = e.CCUsers,
                                Subject = e.Subject,
                                Message = e.Message,
                                CreatedOn = e.CreatedOn
                            }).OrderByDescending(o => o.EmailLogId).ToPagedList(_filter.PageNumber, _filter.PageSize);

                int TotalRecord = temp.TotalCount;
                rType = temp;
                rType.ForEach(s => s.TotalRecords = TotalRecord);
            }
            return rType;
        }
        #endregion
Here method ToPagedList is used for custom paging.

Step 6- Add new Entity PagingEntity
 public class PagingEntity
    {
        public int TotalPages { get; set; }
        public int PageSize { get; set; }
        public int TotalRecords { get; set; }
        public int CurrentPage { get; set; }
    }

Step 7- Add new Partial View _PagingPartial.cshtm
@model PagingEntity


@if (Model.CurrentPage > 0 && Model.TotalPages > 0)
{
    <div class="text-center">
        <ul class="pagination">
            @if (Model.CurrentPage == 1)
            {
                <li class="disabled"><a class="disabled">Previous</a></li>
            }
            else
            {
                <li><a href="#" onclick="PageClicked('@(Model.CurrentPage-1)');">Previous</a></li>
            }

            @if (Model.CurrentPage < 5)
            {
                <li @(Model.CurrentPage == 1 ? "class=active" : "")><a href="#" onclick="PageClicked('1');">1</a></li>
                if (@Model.TotalPages > 2)
                {
                    <li @(Model.CurrentPage == 2 ? "class=active" : "")><a href="#" onclick="PageClicked('2');">2</a></li>
                }
                if (@Model.TotalPages > 3)
                {
                    <li @(Model.CurrentPage == 3 ? "class=active" : "")><a href="#" onclick="PageClicked('3');">3</a></li>
                }
                if (@Model.TotalPages > 4)
                {
                    <li @(Model.CurrentPage == 4 ? "class=active" : "")><a href="#" onclick="PageClicked('4');">4</a></li>
                }
                if (@Model.TotalPages > 5)
                {
                    <li @(Model.CurrentPage == 5 ? "class=active" : "")><a href="#" onclick="PageClicked('5');">5</a></li>
                }
                if (Model.TotalPages > 5)
                {
                    <li class="disabled"><a href="#">...</a></li>
                    <li><a href="#" onclick="PageClicked('@(Model.TotalPages)');">@(Model.TotalPages)</a></li>
                }
            }
            else if (Model.CurrentPage >= 5 && Model.CurrentPage <= Model.TotalPages - 4)
            {
                <li><a href="#" onclick="PageClicked('1');">1</a></li>
                if (Model.TotalPages > 5)
                {
                    <li class="disabled"><a href="#">...</a></li>
                }
                <li><a href="#" onclick="PageClicked('@(Model.CurrentPage-1)');">@(Model.CurrentPage - 1)</a></li>
                <li class="active"><a href="#" onclick="PageClicked('@(Model.CurrentPage)');">@(Model.CurrentPage)</a></li>
                <li><a href="#" onclick="PageClicked('@(Model.CurrentPage+1)');">@(Model.CurrentPage + 1)</a></li>
                <li class="disabled"><a href="#">...</a></li>
                <li><a href="#" onclick="PageClicked('@(Model.TotalPages)');">@(Model.TotalPages)</a></li>
            }

            else if (Model.CurrentPage > Model.TotalPages - 4)
            {
                <li><a href="#" onclick="PageClicked('1');">1</a></li>
                <li class="disabled"><a href="#">...</a></li>
                if ((Model.TotalPages - 4) > 2)
                {
                    <li><a href="#" onclick="PageClicked('@(Model.TotalPages-4)');">@(Model.TotalPages - 4)</a></li>
                }
                <li @(Model.TotalPages - 3 == Model.CurrentPage ? "class=active" : "")><a href="#" onclick="PageClicked('@(Model.TotalPages-3)');">@(Model.TotalPages - 3)</a></li>
                <li @(Model.TotalPages - 2 == Model.CurrentPage ? "class=active" : "")><a href="#" onclick="PageClicked('@(Model.TotalPages-2)');">@(Model.TotalPages - 2)</a></li>
                <li @(Model.TotalPages - 1 == Model.CurrentPage ? "class=active" : "")><a href="#" onclick="PageClicked('@(Model.TotalPages-1)');">@(Model.TotalPages - 1)</a></li>
                <li @(Model.TotalPages == Model.CurrentPage ? "class=active" : "")><a href="javascript:void(0)" onclick="PageClicked('@(Model.TotalPages)');">@(Model.TotalPages)</a></li>
            }

            @if (Model.CurrentPage == Model.TotalPages)
            {
                <li class="disabled"><a href="javascript:void(0);">Next</a></li>
            }
            else
            {
                <li><a href="javascript:void(0);" onclick="PageClicked('@(Model.CurrentPage+1)');">Next</a></li>
            }
        </ul>
        <div style="display:none;">
            <input type="submit" id="btnSavepaging" />
        </div>
        @Html.Hidden("PageNumber", "1")

        <script type="text/javascript">
            function PageClicked(id) {
                $('#PageNumber').val(id);
                $('#btnSavepaging').click();
            }
        </script>
    </div>
}

Step 8- Add new Action Method for paging
public ActionResult GetPaging(int CurrentPage, int PageSize, int TotalRecords)
        {
            PagingEntity model = new PagingEntity();
            int TotalPages = 0;
            if (PageSize != 0)
            {
                var remainder = TotalRecords % PageSize;
                TotalPages = (TotalRecords / PageSize) + (remainder == 0 ? 0 : 1);
            }
            model.TotalPages = TotalPages;
            model.PageSize = PageSize;
            model.TotalRecords = TotalRecords;
            model.CurrentPage = CurrentPage;
            return PartialView("_PagingPartial", model);
        }

Step 9- Call paging
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public ActionResult EmailLogs(FormCollection collection)
        {
            int PageNumber = 1;
            if(collection["PageNumber"]!=null)
            {
                int.TryParse(collection["PageNumber"].ToString(), out PageNumber);
            }
           
            FilterEmailLogs _Filter = new FilterEmailLogs();
            _Filter.PageNumber = PageNumber;
            _Filter.PageSize = 20;            
            List<EmailLogsEntity> model = EmailLogsServices.Instance.GetEmailLogs(_Filter);
            @ViewBag.CurrentPageNumber = _Filter.PageNumber;
            @ViewBag.TotalRecords = model.Count>0?model[0].TotalRecords:0;
            @ViewBag.PageSize = _Filter.PageSize;
            return View(model);
        }

Step 10- Call Paging from View
@using (Html.BeginForm("EmailLogs", "Your_Controller", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    {        
            <table>
                        @foreach (var item in Model)
                        {
                            <tr id="@("package" + item.EmailLogId)" class="accordion-toggle" data-toggle="collapse" data-parent="#OrderPackages" data-target="@(".packageDetails" + item.EmailLogId)">
                                <td>@Html.DisplayFor(modelItem => item.EmailLogId)</td>
                                <td>@Html.DisplayFor(modelItem => item.Subject)</td>
                                <td>@HRMWeb.Helpers.HRMHtmlHelper.DisplayLocalTime(Html, item.CreatedOn)</td>
                                <td>
                                    <i class="indicator glyphicon glyphicon-chevron-up pull-right"></i>
                                </td>
                            </tr>
                            <tr>
                                <td colspan="4" class="hiddenRow">
                                    <div class="accordion-body collapse @("packageDetails" + item.EmailLogId)" id="@("accordion" + item.EmailLogId)">
                                        <table>
                                            <tr>
                                                <td><b>Message:</b><br />@Html.Raw(item.Message)</td>
                                            </tr>
                                            <tr>
                                                <td>
                                                    <b>To Users:</b><br />
                                                    @Html.DisplayFor(modelItem => item.ToUsers)

                                                </td>
                                            </tr>
                                            <tr>
                                                <td>
                                                    <b>CC Users:</b><br />
                                                    @Html.DisplayFor(modelItem => item.CCUsers)

                                                </td>
                                            </tr>
                                            <tr>
                                                <td>
                                                    <b>Sent By:</b>
                                                    <br />
                                                    @Html.DisplayFor(modelItem => item.FromUserName)

                                                </td>
                                            </tr>
                                        </table>
                                    </div>
                                </td>
                            </tr>
                        }
                        <tr></tr>
                    </tbody>

                </table>

                @Html.Action("GetPaging", "Announcement", new { CurrentPage = (@ViewBag.CurrentPageNumber == null ? 0 : (int)@ViewBag.CurrentPageNumber), PageSize = (@ViewBag.PageSize == null ? 0 : (int)@ViewBag.PageSize), TotalRecords = (@ViewBag.TotalRecords == null ? 0 : ((int)@ViewBag.TotalRecords)) })

            </div>
        </div>
    }
Call Action GetPaging & pass all data from ViewBag(Current page Number, Total Records) Paging will occurs on page.

0 comments :

Post a Comment

  • Popular Posts
  • Comments