Try your search with a different keyword or use * as a wildcard.
//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
}