Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

Pager.cs

//Contributor : MVCContrib

using System.Text;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
using Nop.Core;
using Nop.Core.Infrastructure;
using Nop.Services.Localization;
using Nop.Web.Framework.Extensions;

namespace Nop.Web.Framework.UI.Paging;

/// 
/// Renders a pager component from an IPageableModel datasource.
/// 
public partial class Pager : IHtmlContent
{
    #region Properties

    /// 
    /// ViewContext
    /// 
    public ViewContext ViewContext { get; set; }

    #endregion

    #region Fields

    /// 
    /// Page query string prameter name
    /// 
    protected string _queryParam = "page";

    /// 
    /// A value indicating whether to show Total summary
    /// 
    protected bool _showTotalSummary = false;

    /// 
    /// A value indicating whether to show pager items
    /// 
    protected bool _showPagerItems = true;

    /// 
    /// A value indicating whether to show the first item
    /// 
    protected bool _showFirst = true;

    /// 
    /// A value indicating whether to the previous item
    /// 
    protected bool _showPrevious = true;

    /// 
    /// A value indicating whether to show the next item
    /// 
    protected bool _showNext = true;

    /// 
    /// A value indicating whether to show the last item
    /// 
    protected bool _showLast = true;

    /// 
    /// A value indicating whether to show individual page
    /// 
    protected bool _showIndividualPages = true;

    /// 
    /// A value indicating whether to render empty query string parameters (without values)
    /// 
    protected bool _renderEmptyParameters = true;

    /// 
    /// Number of individual page items to display
    /// 
    protected int _individualPagesDisplayedCount = 5;

    /// 
    /// Boolean parameter names
    /// 
    protected IList _booleanParameterNames = new List();

    /// 
    /// First page css class name
    /// 
    protected string _firstPageCssClass = "first-page";

    /// 
    /// Previous page css class name
    /// 
    protected string _previousPageCssClass = "previous-page";

    /// 
    /// Current page css class name
    /// 
    protected string _currentPageCssClass = "current-page";

    /// 
    /// Individual page css class name
    /// 
    protected string _individualPageCssClass = "individual-page";

    /// 
    /// Next page css class name
    /// 
    protected string _nextPageCssClass = "next-page";

    /// 
    /// Last page css class name
    /// 
    protected string _lastPageCssClass = "last-page";

    /// 
    /// Main ul css class name
    /// 
    protected string _mainUlCssClass = string.Empty;

    protected readonly IPageableModel _model;

    #endregion

    #region Ctor

    public Pager(IPageableModel model, ViewContext context)
    {
        _model = model;
        ViewContext = context;
    }

    #endregion

    #region Methods

    #region Fields setters

    /// 
    /// Set 
    /// 
    /// Value
    /// Pager
    public Pager QueryParam(string value)
    {
        _queryParam = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to show Total summary
    /// 
    /// Value
    /// Pager
    public Pager ShowTotalSummary(bool value)
    {
        _showTotalSummary = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to show pager items
    /// 
    /// Value
    /// Pager
    public Pager ShowPagerItems(bool value)
    {
        _showPagerItems = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to show the first item
    /// 
    /// Value
    /// Pager
    public Pager ShowFirst(bool value)
    {
        _showFirst = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to the previous item
    /// 
    /// Value
    /// Pager
    public Pager ShowPrevious(bool value)
    {
        _showPrevious = value;
        return this;
    }

    /// 
    /// Set a  value indicating whether to show the next item
    /// 
    /// Value
    /// Pager
    public Pager ShowNext(bool value)
    {
        _showNext = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to show the last item
    /// 
    /// Value
    /// Pager
    public Pager ShowLast(bool value)
    {
        _showLast = value;
        return this;
    }

    /// 
    /// Set number of individual page items to display
    /// 
    /// Value
    /// Pager
    public Pager ShowIndividualPages(bool value)
    {
        _showIndividualPages = value;
        return this;
    }

    /// 
    /// Set a value indicating whether to render empty query string parameters (without values)
    /// 
    /// Value
    /// Pager
    public Pager RenderEmptyParameters(bool value)
    {
        _renderEmptyParameters = value;
        return this;
    }

    /// 
    /// Set number of individual page items to display
    /// 
    /// Value
    /// Pager
    public Pager IndividualPagesDisplayedCount(int value)
    {
        _individualPagesDisplayedCount = value;
        return this;
    }

    /// 
    /// little hack here due to ugly MVC implementation
    /// find more info here: http://www.mindstorminteractive.com/topics/jquery-fix-asp-net-mvc-checkbox-truefalse-value/
    /// 
    /// Parameter name
    /// Pager
    public Pager BooleanParameterName(string paramName)
    {
        _booleanParameterNames.Add(paramName);
        return this;
    }

    /// 
    /// Set first page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager FirstPageCssClass(string value)
    {
        _firstPageCssClass = value;
        return this;
    }

    /// 
    /// Set previous page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager PreviousPageCssClass(string value)
    {
        _previousPageCssClass = value;
        return this;
    }

    /// 
    /// Set current page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager CurrentPageCssClass(string value)
    {
        _currentPageCssClass = value;
        return this;
    }

    /// 
    /// Set individual page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager IndividualPageCssClass(string value)
    {
        _individualPageCssClass = value;
        return this;
    }

    /// 
    /// Set next page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager NextPageCssClass(string value)
    {
        _nextPageCssClass = value;
        return this;
    }

    /// 
    /// Set last page pager css class name
    /// 
    /// Value
    /// Pager
    public Pager LastPageCssClass(string value)
    {
        _lastPageCssClass = value;
        return this;
    }

    /// 
    /// Set main ul css class name
    /// 
    /// Value
    /// Pager
    public Pager MainUlCssClass(string value)
    {
        _mainUlCssClass = value;
        return this;
    }

    #endregion

    /// 
    /// Write control
    /// 
    /// Writer
    /// Encoder
    public void WriteTo(TextWriter writer, HtmlEncoder encoder)
    {
        writer.Write(ToString());
    }

    /// 
    /// Generate HTML control
    /// 
    /// HTML control
    public override string ToString()
    {
        return GenerateHtmlStringAsync().Result;
    }

    /// 
    /// Is pager empty (only one page)?
    /// 
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    public virtual async Task IsEmpty()
    {
        return string.IsNullOrEmpty(await GenerateHtmlStringAsync());
    }

    #endregion

    #region Utilities

    /// 
    /// Generate HTML control
    /// 
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the hTML control
    /// 
    protected virtual async Task GenerateHtmlStringAsync()
    {
        if (_model.TotalItems == 0)
            return null;

        var localizationService = EngineContext.Current.Resolve();

        var links = new StringBuilder();
        if (_showTotalSummary && (_model.TotalPages > 0))
        {
            links.Append("
  • "); links.Append(string.Format(await localizationService.GetResourceAsync("Pager.CurrentPage"), _model.PageIndex + 1, _model.TotalPages, _model.TotalItems)); links.Append("
  • "); } if (_showPagerItems && (_model.TotalPages > 1)) { if (_showFirst) { //first page if ((_model.PageIndex >= 3) && (_model.TotalPages > _individualPagesDisplayedCount)) links.Append(await CreatePageLinkAsync(1, await localizationService.GetResourceAsync("Pager.First"), _firstPageCssClass)); } if (_showPrevious) { //previous page if (_model.PageIndex > 0) links.Append(await CreatePageLinkAsync(_model.PageIndex, await localizationService.GetResourceAsync("Pager.Previous"), _previousPageCssClass)); } if (_showIndividualPages) { //individual pages var firstIndividualPageIndex = GetFirstIndividualPageIndex(); var lastIndividualPageIndex = GetLastIndividualPageIndex(); for (var i = firstIndividualPageIndex; i <= lastIndividualPageIndex; i++) { if (_model.PageIndex == i) links.AppendFormat("
  • {0}
  • ", (i + 1)); else links.Append(await CreatePageLinkAsync(i + 1, (i + 1).ToString(), _individualPageCssClass)); } } if (_showNext) { //next page if ((_model.PageIndex + 1) < _model.TotalPages) links.Append(await CreatePageLinkAsync(_model.PageIndex + 2, await localizationService.GetResourceAsync("Pager.Next"), _nextPageCssClass)); } if (_showLast) { //last page if (((_model.PageIndex + 3) < _model.TotalPages) && (_model.TotalPages > _individualPagesDisplayedCount)) links.Append(await CreatePageLinkAsync(_model.TotalPages, await localizationService.GetResourceAsync("Pager.Last"), _lastPageCssClass)); } } var result = links.ToString(); if (!string.IsNullOrEmpty(result)) result = string.Format("", string.IsNullOrEmpty(_mainUlCssClass) ? "" : " class=\"" + _mainUlCssClass + "\"") + result + ""; return result; } /// /// Get first individual page index /// /// Page index protected virtual int GetFirstIndividualPageIndex() { if ((_model.TotalPages < _individualPagesDisplayedCount) || ((_model.PageIndex - (_individualPagesDisplayedCount / 2)) < 0)) return 0; if ((_model.PageIndex + (_individualPagesDisplayedCount / 2)) >= _model.TotalPages) return _model.TotalPages - _individualPagesDisplayedCount; return _model.PageIndex - (_individualPagesDisplayedCount / 2); } /// /// Get last individual page index /// /// Page index protected virtual int GetLastIndividualPageIndex() { var num = _individualPagesDisplayedCount / 2; if ((_individualPagesDisplayedCount % 2) == 0) num--; if ((_model.TotalPages < _individualPagesDisplayedCount) || ((_model.PageIndex + num) >= _model.TotalPages)) return _model.TotalPages - 1; if ((_model.PageIndex - (_individualPagesDisplayedCount / 2)) < 0) return _individualPagesDisplayedCount - 1; return _model.PageIndex + num; } /// /// Create page link /// /// Page number /// Text /// CSS class /// /// A task that represents the asynchronous operation /// The task result contains the link /// protected virtual async Task CreatePageLinkAsync(int pageNumber, string text, string cssClass) { var liBuilder = new TagBuilder("li"); if (!string.IsNullOrWhiteSpace(cssClass)) liBuilder.AddCssClass(cssClass); var aBuilder = new TagBuilder("a"); aBuilder.InnerHtml.AppendHtml(text); aBuilder.MergeAttribute("data-page", pageNumber.ToString()); aBuilder.MergeAttribute("href", CreateDefaultUrl(pageNumber)); liBuilder.InnerHtml.AppendHtml(aBuilder); return await liBuilder.RenderHtmlContentAsync(); } /// /// Create default URL /// /// Page number /// URL protected virtual string CreateDefaultUrl(int pageNumber) { var routeValues = new RouteValueDictionary(); var parametersWithEmptyValues = new List(); foreach (var key in ViewContext.HttpContext.Request.Query.Keys.Where(key => key != null)) { var value = ViewContext.HttpContext.Request.Query[key].ToString(); if (_renderEmptyParameters && string.IsNullOrEmpty(value)) { //we store query string parameters with empty values separately //we need to do it because they are not properly processed in the UrlHelper.GenerateUrl method (dropped for some reasons) parametersWithEmptyValues.Add(key); } else { if (_booleanParameterNames.Contains(key, StringComparer.InvariantCultureIgnoreCase)) { //little hack here due to ugly MVC implementation //find more info here: http://www.mindstorminteractive.com/topics/jquery-fix-asp-net-mvc-checkbox-truefalse-value/ if (!string.IsNullOrEmpty(value) && value.Equals("true,false", StringComparison.InvariantCultureIgnoreCase)) value = "true"; } routeValues[key] = value; } } if (pageNumber > 1) routeValues[_queryParam] = pageNumber; else { //SEO. we do not render pageindex query string parameter for the first page if (routeValues.ContainsKey(_queryParam)) routeValues.Remove(_queryParam); } var webHelper = EngineContext.Current.Resolve(); var url = webHelper.GetThisPageUrl(false); foreach (var routeValue in routeValues) url = webHelper.ModifyQueryString(url, routeValue.Key, routeValue.Value?.ToString()); if (_renderEmptyParameters && parametersWithEmptyValues.Any()) foreach (var key in parametersWithEmptyValues) url = webHelper.ModifyQueryString(url, key); return url; } #endregion }