stho01
4/26/2017 - 12:31 PM

A rolling MVC list paging view used for create a paging UI for lists

A rolling MVC list paging view used for create a paging UI for lists

using EPiServer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;

namespace WebApplication.Models.View
{
    public class PagingViewModel
    {
        //**********************************************
        //** Properties
        //**********************************************
        
        public int CurrentPage { get; set; }
        public int ItemsPerPage { get; set; }
        public int ItemsPerPageMobile { get; set; }
        public int TotalItemCount { get; set; }
        public IEnumerable<string> CssClasses { get; set; }
        public string CssClassString => CssClasses != null ? string.Join(" ", CssClasses) : null;

        /// <summary>
        /// The total number of pages
        /// </summary>
        public int TotalPageCount
        {
            get
            {
                if (ItemsPerPage == 0) return 0;
                return 1 + (TotalItemCount - 1) / ItemsPerPage;
            }
        }
        
        public int CurrentStartIndex
        {
            get
            {
                if (CurrentPage <= ItemsPerPageHalf)
                    return 1;
                else if (CurrentPage >= (TotalPageCount - ItemsPerPageHalf))
                    return Math.Max(TotalPageCount - ItemsPerPage + 1, 1);
                else
                    return Math.Max(CurrentPage - ItemsPerPageHalf, 1);
            }
        }

        public int CurrentEndIndex
        {
            get
            {
                if (CurrentPage <= ItemsPerPageHalf)
                    return ItemsPerPage;
                else if (CurrentPage > (TotalPageCount - ItemsPerPageHalf))
                    return TotalPageCount;
                else
                    return Math.Min(TotalItemCount, (CurrentPage + ItemsPerPageHalf));
            }
        }

        private int ItemsPerPageHalf => ItemsPerPage / 2;

        private int TotalPageCountHalf
        {
            get
            {
                var half = (TotalPageCount / 2);
                return half;
            }
        }
    
        //**********************************************
        //** Constructors
        //**********************************************

        public PagingViewModel(int currentPage, int itemsPerPage, int totalItemCount)
        {
            CurrentPage             = currentPage;
            ItemsPerPage            = itemsPerPage;
            TotalItemCount          = totalItemCount;
            ItemsPerPageMobile      = 3;
        }
        
        //**********************************************
        //** Public methods
        //**********************************************

        public string GetPagingUrl(int pageNumber)
        {
            // TODO: Remove EPiServer reference...
            return UriSupport.AddQueryString(HttpContext.Current.Request.RawUrl, "p", pageNumber.ToString());
        }

        public bool IsItemVisibleOnMobile(int itemIndex)
        {
            var half = ItemsPerPageMobile/2;
            if (itemIndex <= ItemsPerPageMobile && CurrentPage <= half)
                return true;
            if (itemIndex > (TotalPageCount - ItemsPerPageMobile) && CurrentPage > (TotalPageCount - half))
                return true;
            
            var inRange = (half) >= Math.Abs(CurrentPage - itemIndex);
            return inRange;
        }
    }
}
@model WebApplication.Models.View.PagingViewModel

@if (Model.TotalPageCount > 1)
{
    <ul class="paging align-center">
        @* Previous page *@
        @if (Model.CurrentPage > 1)
        {
            <li class="paging__prev"><a href="@Model.GetPagingUrl(Model.CurrentPage - 1)">Forrige</a></li>
        }
        @for (int pageNumber = Model.CurrentStartIndex; pageNumber <= Model.CurrentEndIndex; pageNumber++)
        {
            if (Model.CurrentPage == pageNumber)
            {
                <li class="paging__num paging__active"><span>@pageNumber</span></li>
            }
            else if (Model.IsItemVisibleOnMobile(pageNumber))
            {
                <li class="paging__num paging__num--mobile"><a href="@Model.GetPagingUrl(pageNumber)">@pageNumber</a></li>
            }
            else
            {
                <li class="paging__num"><a href="@Model.GetPagingUrl(pageNumber)">@pageNumber</a></li>
            }
        }
        @* Next page *@
        @if (Model.CurrentPage < Model.TotalPageCount)
        {
            <li class="paging__next"><a href="@Model.GetPagingUrl(Model.CurrentPage + 1)">Neste</a></li>
        }
    </ul>
}