Skip to content

Commit

Permalink
Pager Shape (#5506)
Browse files Browse the repository at this point in the history
  • Loading branch information
Skrypt committed Feb 14, 2020
1 parent ff1dc82 commit 7c0dfcc
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 131 deletions.
177 changes: 79 additions & 98 deletions src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
}

[Shape]
public async Task<IHtmlContent> Pager_Links(Shape Shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, DisplayContext DisplayContext,
public async Task<IHtmlContent> Pager_Links(Shape shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, DisplayContext DisplayContext,
string PagerId,
int Page,
int PageSize,
Expand All @@ -165,21 +165,11 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
object GapText,
bool ShowNext,
string ItemTagName,
IDictionary<string, string> Attributes,
IDictionary<string, string> ItemAttributes
// parameter omitted to workaround an issue where a NullRef is thrown
// when an anonymous object is bound to an object shape parameter
/*object RouteValues*/)
{
Shape.Properties["ItemTagName"] = ItemTagName;
Shape.Properties["ItemAttributes"] = ItemAttributes;

var attributes = Shape.Attributes;
foreach (var item in Attributes)
{
attributes.Add(item.Key, item.Value);
}

var currentPage = Page;
if (currentPage < 1)
currentPage = 1;
Expand All @@ -195,8 +185,8 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
// return shape early if pager is not needed.
if (totalPageCount < 2)
{
Shape.Metadata.Type = "List";
return await DisplayAsync(Shape);
shape.Metadata.Type = "List";
return await DisplayAsync(shape);
}

var firstText = FirstText ?? S["<<"];
Expand All @@ -223,7 +213,7 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
}

// specific cross-requests route data can be passed to the shape directly (e.g., OrchardCore.Users)
var shapeRoute = (object)((dynamic)Shape).RouteData;
var shapeRoute = (object)((dynamic)shape).RouteData;

if (shapeRoute != null)
{
Expand All @@ -246,14 +236,14 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
}
}

int firstPage = Math.Max(1, Page - (numberOfPagesToShow / 2));
int lastPage = Math.Min(totalPageCount, Page + (int)(numberOfPagesToShow / 2));
var firstPage = Math.Max(1, Page - (numberOfPagesToShow / 2));
var lastPage = Math.Min(totalPageCount, Page + (int)(numberOfPagesToShow / 2));

var pageKey = String.IsNullOrEmpty(PagerId) ? "page" : PagerId;

Shape.Classes.Add("pager");
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "List";
shape.Classes.Add("pager");
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "List";

// first and previous pages
if ((Page > 1) && (routeData.ContainsKey(pageKey)))
Expand All @@ -262,20 +252,20 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
}

// first
Shape.Add(await New.Pager_First(Value: firstText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape, Disabled: Page < 2));
shape.Add(await New.Pager_First(Value: firstText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page < 2));

// previous
if ((Page > 1) && (currentPage > 2))
{ // also to keep from having "page=1" in the query string
routeData[pageKey] = currentPage - 1;
}
Shape.Add(await New.Pager_Previous(Value: previousText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape, Disabled: Page < 2));
shape.Add(await New.Pager_Previous(Value: previousText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page < 2));


// gap at the beginning of the pager
if (firstPage > 1 && numberOfPagesToShow > 0)
{
Shape.Add(await New.Pager_Gap(Value: gapText, Pager: Shape));
shape.Add(await New.Pager_Gap(Value: gapText, Pager: shape));
}

// page numbers
Expand All @@ -286,71 +276,60 @@ public PagerShapes(IStringLocalizer<PagerShapes> localizer)
if (p == currentPage)
{
routeData[pageKey] = currentPage;
Shape.Add(await New.Pager_CurrentPage(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
shape.Add(await New.Pager_CurrentPage(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: shape));
}
else
{
if (p == 1)
routeData.Remove(pageKey);
else
routeData[pageKey] = p;
Shape.Add(await New.Pager_Link(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
shape.Add(await New.Pager_Link(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: shape));
}
}
}

// gap at the end of the pager
if (lastPage < totalPageCount && numberOfPagesToShow > 0)
{
Shape.Add(await New.Pager_Gap(Value: gapText, Pager: Shape));
shape.Add(await New.Pager_Gap(Value: gapText, Pager: shape));
}

// Next
routeData[pageKey] = Page + 1;
Shape.Add(await New.Pager_Next(Value: nextText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape, Disabled: Page >= totalPageCount && !ShowNext));
shape.Add(await New.Pager_Next(Value: nextText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page >= totalPageCount && !ShowNext));

// Last
routeData[pageKey] = totalPageCount;
Shape.Add(await New.Pager_Last(Value: lastText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape, Disabled: Page >= totalPageCount));
shape.Add(await New.Pager_Last(Value: lastText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page >= totalPageCount));

return await DisplayAsync(Shape);
return await DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Links";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Links";
return DisplayAsync(shape);
}

[Shape]
public async Task<IHtmlContent> PagerSlim(Shape Shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, DisplayContext DisplayContext,
public async Task<IHtmlContent> PagerSlim(Shape shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, DisplayContext DisplayContext,
object PreviousText,
object NextText,
string PreviousClass,
string NextClass,
string ItemTagName,
IDictionary<string, string> Attributes,
IDictionary<string, string> ItemAttributes,
Dictionary<string, string> UrlParams)
{
Shape.Properties["ItemTagName"] = ItemTagName;

var attributes = Shape.Attributes;
foreach (var item in Attributes)
{
attributes.Add(item.Key, item.Value);
}

Shape.Properties["ItemAttributes"] = ItemAttributes;

var previousText = PreviousText ?? S["<"];
var nextText = NextText ?? S[">"];

Shape.Classes.Add("pager");
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "List";
shape.Classes.Add("pager");
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "List";

var routeData = new RouteValueDictionary(Html.ViewContext.RouteData.Values);

Expand All @@ -363,85 +342,91 @@ public Task<IHtmlContent> Pager(Shape Shape, dynamic DisplayAsync)
}
}

if (Shape.Properties.TryGetValue("Before", out var beforeValue) && beforeValue is string before)
if (shape.Properties.TryGetValue("Before", out var beforeValue) && beforeValue is string before)
{
var beforeRouteData = new RouteValueDictionary(routeData);
beforeRouteData["before"] = before;
Shape.Add(await New.Pager_Previous(Value: previousText, RouteValues: beforeRouteData, Pager: Shape));
Shape.Properties["FirstClass"] = PreviousClass;
var beforeRouteData = new RouteValueDictionary(routeData)
{
["before"] = before
};
shape.Add(await New.Pager_Previous(Value: previousText, RouteValues: beforeRouteData, Pager: shape));
shape.Properties["FirstClass"] = PreviousClass;
}

if (Shape.Properties.TryGetValue("After", out var afterValue) && afterValue is string after)
if (shape.Properties.TryGetValue("After", out var afterValue) && afterValue is string after)
{
var afterRouteData = new RouteValueDictionary(routeData);
afterRouteData["after"] = after;
Shape.Add(await New.Pager_Next(Value: nextText, RouteValues: afterRouteData, Pager: Shape));
Shape.Properties["LastClass"] = NextClass;
var afterRouteData = new RouteValueDictionary(routeData)
{
["after"] = after
};
shape.Add(await New.Pager_Next(Value: nextText, RouteValues: afterRouteData, Pager: shape));
shape.Properties["LastClass"] = NextClass;
}

return await DisplayAsync(Shape);
return await DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_First(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_First(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
return DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_Previous(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_Previous(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
return DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_CurrentPage(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_CurrentPage(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
var parentTag = (TagBuilder)Shape.Properties["Tag"];
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
var parentTag = (TagBuilder)shape.Properties["Tag"];
parentTag.AddCssClass("active");
return DisplayAsync(Shape);
return DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_Next(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_Next(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
return DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_Last(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_Last(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
return DisplayAsync(shape);
}

[Shape]
public Task<IHtmlContent> Pager_Link(IHtmlHelper Html, Shape Shape, dynamic DisplayAsync, object Value)
public Task<IHtmlContent> Pager_Link(Shape shape, IHtmlHelper Html, dynamic DisplayAsync, object Value)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "ActionLink";
return DisplayAsync(Shape);
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "ActionLink";
return DisplayAsync(shape);
}

[Shape]
public IHtmlContent ActionLink(IUrlHelper Url, Shape Shape, object Value, bool Disabled = false)
public IHtmlContent ActionLink(Shape shape, IUrlHelper Url, object Value, bool Disabled = false)
{
if (Disabled)
{
var parentLiTag = (TagBuilder)Shape.Properties["Tag"];
parentLiTag.AddCssClass("disabled");
if (shape.Properties.TryGetValue("Tag", out var value) && value is TagBuilder tagBuilder)
{
tagBuilder.AddCssClass("disabled");
}
}

var RouteValues = (object)((dynamic)Shape).RouteValues;
var RouteValues = (object)((dynamic)shape).RouteValues;
RouteValueDictionary rvd;
if (RouteValues == null)
{
Expand All @@ -452,25 +437,21 @@ public IHtmlContent ActionLink(IUrlHelper Url, Shape Shape, object Value, bool D
rvd = RouteValues as RouteValueDictionary ?? new RouteValueDictionary(RouteValues);
}

var action = Url.Action((string)rvd["action"], (string)rvd["controller"], rvd);

IEnumerable<string> classes = Shape.Classes;
IDictionary<string, string> attributes = Shape.Attributes;
attributes["href"] = action;
var tag = Shape.GetTagBuilder("a", null, classes, attributes);
shape.Attributes["href"] = Url.Action((string)rvd["action"], (string)rvd["controller"], rvd);
var tag = Shape.GetTagBuilder("a", null, shape.Classes, shape.Attributes);

tag.InnerHtml.AppendHtml(CoerceHtmlString(Value));
return tag;
}

[Shape]
public Task<IHtmlContent> Pager_Gap(Shape Shape, dynamic DisplayAsync)
public Task<IHtmlContent> Pager_Gap(Shape shape, dynamic DisplayAsync)
{
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Link";
var parentTag = (TagBuilder)Shape.Properties["Tag"];
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "Pager_Link";
var parentTag = (TagBuilder)shape.Properties["Tag"];
parentTag.AddCssClass("disabled");
return DisplayAsync(Shape);
return DisplayAsync(shape);
}

private IHtmlContent CoerceHtmlString(object value)
Expand Down

0 comments on commit 7c0dfcc

Please sign in to comment.