Paging TagHelper for ASP NET Core

Simple to use, fully customizable pagination tag helper for ASP.NET Core 2.1 projects

Having a good pagination control is an important part for every web project. I created this control while working on a web project based on ASP.NET Core 2.1 and bootstrap 4.1, The idea is to have a simple usage and maximum customization with minimal setup requirements.

Project on github: https://github.com/LazZiya/TagHelpers/

Live demo page: http://demo.ziyad.info/en/paging

 

Available in v1.0.2 and v1.0.3 :

- Settings via HTML tags

- Settings via json

 

Installation instructions:

Download latest nuget package (v1.0.3) either by searching for "LazZiya.TagHelpers" or by using package manager console:

Install-Package LazZiya.TagHelpers -Version 1.0.2

add PagingTagHelper library to your _ViewImports.cshtml file :

@addTagHelper *, LazZiya.TagHelpers

add paging tag wherever you need paging pagination control as simple as below:

<paging total-records="Model.TotalRecords" page-no="Model.PageNo">
</paging>

Assigning data values:

total-records and page-no are required parameters, it is recommended to provide them as model property or via ViewData. page-size is required if page size dropdown navigatin is enabled, otherwise it will be 10 by default.

 

Search filters :

If you have multiple search parameters that is used for getting the paged data, add query-string-value parameter as below to include search filters :

<paging 
    total-records="Model.TotalRecords" 
    page-no="Model.PageNo"
    query-string-value="@(Request.QueryString.Value)">
</paging>

 

For example, the below code is getting a list of all cultures in the system and returns only requested amount "page-size" starting from desired position "page-no".

total-records, page-no and page-size vaules can be assigned as below:

 

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace LiveDemos.Pages
{
    public class PagingModel : PageModel
    {
        [BindProperty]
        public IEnumerable<CultureInfo> Cultures { get; set; }

        [BindProperty]
        public int TotalRecords { get; set; }

        [BindProperty]
        public int PageNo { get; set; }

        [BindProperty]
        public int PageSize { get; set; }

        public void OnGet(int p = 1, int s = 10)
        {
            Cultures = CultureInfo.GetCultures(CultureTypes.AllCultures)
                .OrderBy(x => x.EnglishName).Skip((p - 1) * s).Take(s);

            TotalRecords = CultureInfo.GetCultures(CultureTypes.AllCultures).Count();
            PageNo = p;
            PageSize = s; // required if page size dropdown is enabled
        }
    }
}

 

PaginTagHelper can be customized and it supports localization and style customization. Here is a full list of PagingTagHelper properties:

 

<paging total-records="Model.TotalRecords"
            page-no="Model.PageNo"
            page-size="Model.PageSize"
            show-prev-next="true"
            show-total-pages="true"
            show-total-records="true"
            show-page-size-nav="true"
            show-first-numbered-page="true"
            show-last-numbered-page="true"
            gap-size="2"
            max-displayed-pages="3"
            query-string-key-page-no="p"
            query-string-key-page-size="s"
            query-string-value="@@(Request.QueryString.Value)"
            page-size-nav-block-size="10"
            page-size-nav-max-items="3"
            page-size-nav-on-change="get"
            page-size-nav-form-method="this.form.submit();"
            class="row"
            class-paging-control-div="col"
            class-info-div="col"
            class-page-size-div="col"
            class-paging-control="pagination"
            class-active-page="disabled"
            class-disabled-jumping-button="disabled"
            class-total-pages="badge badge-secondary"
            class-total-records="badge badge-info"
            text-page-size="Items per page:"
            text-total-pages="pages"
            text-total-records="records"
            text-first="&laquo;"
            text-last="&raquo;"
            text-previous="&lsaquo;"
            text-next="&rsaquo;"
            sr-text-first="First"
            sr-text-last="Last"
            sr-text-previous="Previous"
            sr-text-next="Next">
    </paging>
    

Settings via Json :

If you prefere to keep your html code clean, or if you have multiple pages/areas with different paging requirements you can move all optional settings to appSettings.json file and provide just the required parameters in html code in addition to the settings-json property as below:

 

Sample json for three different paging taghelper settings in appSettings.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "lazziya": {
    "pagingTagHelper": {
      "default": {
        "page-no": 1,
        "page-size": 10,
        "total-records": 0,
        "max-displayed-pages": 10,
        "gap-size": 3,
        "page-size-nav-form-method": "get",
        "page-size-nav-on-change": "this.form.submit();",
        "page-size-nav-block-size": 10,
        "page-size-nav-max-items": 5,
        "query-string-key-page-no": "p",
        "query-string-key-page-size": "s",
        "query-string-value": "",
        "show-first-last": false,
        "show-prev-next": false,
        "show-page-size-nav": false,
        "show-total-pages": false,
        "show-total-records": false,
        "show-first-numbered-page": false,
        "show-last-numbered-page": false,
        "text-page-size": "Items per page",
        "text-first": "«",
        "text-last": "»",
        "text-previous": "‹",
        "text-next": "›",
        "text-total-pages": "pages",
        "text-total-records": "records",
        "sr-text-first": "First",
        "sr-text-last": "Last",
        "sr-text-previous": "Previous",
        "sr-text-next": "Next",
        "class": "row",
        "class-info-div": "col",
        "class-page-size-div": "col",
        "class-paging-control-div": "col",
        "class-paging-control": "pagination",
        "class-active-page": "active",
        "class-disabled-jumping-button": "disabled",
        "class-total-pages": "badge badge-secondary",
        "class-total-records": "badge badge-info"
      },
      "basic": {
        "show-first-last": true,
        "max-displayed-pages": 7,
        "class-active-aage": "disabled"
      },
      "custom": {
        "show-first-last": true,
        "show-prev-next": true,
        "max-displayed-pages": 2,
        "text-first": "go first",
        "text-last": "go last",
        "text-previous": "one step back",
        "text-next": "one step forward",
        "class-paging-control": "pagination pagination-lg"
      },
      "full": {
        "max-displayed-pages": 10,
        "gap-size": 3,
        "show-first-last": true,
        "show-prev-next": true,
        "show-page-size-nav": true,
        "show-total-pages": true,
        "show-total-records": true,
        "show-first-numbered-page": true,
        "show-last-numbered-page": true
      }
    }
  }
}

 

Html code for three different paging helpers with different json settings  :

<!-- custom settings -->
    <paging total-records="Model.TotalRecords" 
            page-no="Model.PageNo" 
            page-size="Model.PageSize" 
            settings-json="custom">
    </paging>

    <!-- basic settings -->
    <paging total-records="Model.TotalRecords" 
            page-no="Model.PageNo" 
            page-size="Model.PageSize" 
            settings-json="basic">
    </paging>

    <!-- full settings -->
    <paging total-records="Model.TotalRecords" 
            page-no="Model.PageNo" 
            page-size="Model.PageSize" 
            settings-json="full">
    </paging>

 

For live demos please visit the live demo page http://demo.ziyad.info/en/paging